diff options
Diffstat (limited to 'src')
49 files changed, 1272 insertions, 864 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index cc274eee22..0fa2762c0f 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -138,6 +138,12 @@ trait Definitions extends reflect.api.StandardDefinitions { // symbols related to packages var emptypackagescope: Scope = null //debug + // TODO - having these as objects means they elude the attempt to + // add synchronization in SynchronizedSymbols. But we should either + // flip on object overrides or find some other accomodation, because + // lazy vals are unnecessarily expensive relative to objects and it + // is very beneficial for a handful of bootstrap symbols to have + // first class identities sealed trait WellKnownSymbol extends Symbol { this initFlags TopLevelCreationFlags } @@ -148,7 +154,7 @@ trait Definitions extends reflect.api.StandardDefinitions { } // This is the package _root_. The actual root cannot be referenced at // the source level, but _root_ is essentially a function => <root>. - final object RootPackage extends ModuleSymbol(NoSymbol, NoPosition, nme.ROOTPKG) with RootSymbol { + final object RootPackage extends PackageSymbol(NoSymbol, NoPosition, nme.ROOTPKG) with RootSymbol { this setInfo NullaryMethodType(RootClass.tpe) RootClass.sourceModule = this @@ -160,7 +166,7 @@ trait Definitions extends reflect.api.StandardDefinitions { // although it is probable that some symbols are created as direct children // of NoSymbol to ensure they will not be stumbled upon. (We should designate // a better encapsulated place for that.) - final object RootClass extends ModuleClassSymbol(NoSymbol, NoPosition, tpnme.ROOT) with RootSymbol { + final object RootClass extends PackageClassSymbol(NoSymbol, NoPosition, tpnme.ROOT) with RootSymbol { this setInfo rootLoader override def isRoot = true @@ -170,10 +176,10 @@ trait Definitions extends reflect.api.StandardDefinitions { override def ownerOfNewSymbols = EmptyPackageClass } // The empty package, which holds all top level types without given packages. - final object EmptyPackage extends ModuleSymbol(RootClass, NoPosition, nme.EMPTY_PACKAGE_NAME) with WellKnownSymbol { + final object EmptyPackage extends PackageSymbol(RootClass, NoPosition, nme.EMPTY_PACKAGE_NAME) with WellKnownSymbol { override def isEmptyPackage = true } - final object EmptyPackageClass extends ModuleClassSymbol(RootClass, NoPosition, tpnme.EMPTY_PACKAGE_NAME) with WellKnownSymbol { + final object EmptyPackageClass extends PackageClassSymbol(RootClass, NoPosition, tpnme.EMPTY_PACKAGE_NAME) with WellKnownSymbol { override def isEffectiveRoot = true override def isEmptyPackageClass = true } @@ -857,7 +863,8 @@ trait Definitions extends reflect.api.StandardDefinitions { // boxed classes lazy val ObjectRefClass = getRequiredClass("scala.runtime.ObjectRef") lazy val VolatileObjectRefClass = getRequiredClass("scala.runtime.VolatileObjectRef") - lazy val BoxesRunTimeClass = getRequiredModule("scala.runtime.BoxesRunTime") + lazy val BoxesRunTimeModule = getRequiredModule("scala.runtime.BoxesRunTime") + lazy val BoxesRunTimeClass = BoxesRunTimeModule.moduleClass lazy val BoxedNumberClass = getClass(sn.BoxedNumber) lazy val BoxedCharacterClass = getClass(sn.BoxedCharacter) lazy val BoxedBooleanClass = getClass(sn.BoxedBoolean) @@ -868,6 +875,9 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val BoxedFloatClass = getRequiredClass("java.lang.Float") lazy val BoxedDoubleClass = getRequiredClass("java.lang.Double") + lazy val Boxes_isNumberOrBool = getDecl(BoxesRunTimeClass, nme.isBoxedNumberOrBoolean) + lazy val Boxes_isNumber = getDecl(BoxesRunTimeClass, nme.isBoxedNumber) + lazy val BoxedUnitClass = getRequiredClass("scala.runtime.BoxedUnit") lazy val BoxedUnitModule = getRequiredModule("scala.runtime.BoxedUnit") def BoxedUnit_UNIT = getMember(BoxedUnitModule, nme.UNIT) @@ -984,13 +994,25 @@ trait Definitions extends reflect.api.StandardDefinitions { else findNamedMember(segs.tail, root.info member segs.head) def getMember(owner: Symbol, name: Name): Symbol = { - if (owner == NoSymbol) NoSymbol - else owner.info.nonPrivateMember(name) match { - case NoSymbol => throw new FatalError(owner + " does not have a member " + name) - case result => result + getMemberIfDefined(owner, name) orElse { + throw new FatalError(owner + " does not have a member " + name) } } + def getMemberIfDefined(owner: Symbol, name: Name): Symbol = + owner.info.nonPrivateMember(name) + /** Using getDecl rather than getMember may avoid issues with + * OverloadedTypes turning up when you don't want them, if you + * know the method in question is uniquely declared in the given owner. + */ + def getDecl(owner: Symbol, name: Name): Symbol = { + getDeclIfDefined(owner, name) orElse { + throw new FatalError(owner + " does not have a decl " + name) + } + } + def getDeclIfDefined(owner: Symbol, name: Name): Symbol = + owner.info.nonPrivateDecl(name) + def packageExists(packageName: String): Boolean = getModuleIfDefined(packageName).isPackage diff --git a/src/compiler/scala/reflect/internal/Flags.scala b/src/compiler/scala/reflect/internal/Flags.scala index ce1c8d0908..38f9ec6669 100644 --- a/src/compiler/scala/reflect/internal/Flags.scala +++ b/src/compiler/scala/reflect/internal/Flags.scala @@ -174,6 +174,9 @@ class Flags extends ModifierFlags { final val LateShift = 47L final val AntiShift = 56L + // Flags which sketchily share the same slot + val OverloadedFlagsMask = 0L | BYNAMEPARAM | CONTRAVARIANT | DEFAULTPARAM | EXISTENTIAL | IMPLCLASS + // ------- late flags (set by a transformer phase) --------------------------------- // // Summary of when these are claimed to be first used. @@ -206,12 +209,24 @@ class Flags extends ModifierFlags { // ------- masks ----------------------------------------------------------------------- + /** To be a little clearer to people who aren't habitual bit twiddlers. + */ + final val AllFlags = -1L + /** These flags can be set when class or module symbol is first created. * They are the only flags to survive a call to resetFlags(). */ final val TopLevelCreationFlags: Long = MODULE | PACKAGE | FINAL | JAVA + // TODO - there's no call to slap four flags onto every package. + final val PackageFlags: Long = TopLevelCreationFlags + + // FINAL not included here due to possibility of object overriding. + // In fact, FINAL should not be attached regardless. We should be able + // to reconstruct whether an object was marked final in source. + final val ModuleFlags: Long = MODULE + /** These modifiers can be set explicitly in source programs. This is * used only as the basis for the default flag mask (which ones to display * when printing a normal message.) @@ -220,15 +235,15 @@ class Flags extends ModifierFlags { PRIVATE | PROTECTED | ABSTRACT | FINAL | SEALED | OVERRIDE | CASE | IMPLICIT | ABSOVERRIDE | LAZY - /** These modifiers appear in TreePrinter output. */ - final val PrintableFlags: Long = - ExplicitFlags | LOCAL | SYNTHETIC | STABLE | CASEACCESSOR | MACRO | - ACCESSOR | SUPERACCESSOR | PARAMACCESSOR | BRIDGE | STATIC | VBRIDGE | SPECIALIZED | SYNCHRONIZED - /** The two bridge flags */ final val BridgeFlags = BRIDGE | VBRIDGE final val BridgeAndPrivateFlags = BridgeFlags | PRIVATE + /** These modifiers appear in TreePrinter output. */ + final val PrintableFlags: Long = + ExplicitFlags | BridgeFlags | LOCAL | SYNTHETIC | STABLE | CASEACCESSOR | MACRO | + ACCESSOR | SUPERACCESSOR | PARAMACCESSOR | STATIC | SPECIALIZED | SYNCHRONIZED + /** When a symbol for a field is created, only these flags survive * from Modifiers. Others which may be applied at creation time are: * PRIVATE, LOCAL. @@ -264,7 +279,7 @@ class Flags extends ModifierFlags { final val ConstrFlags: Long = JAVA /** Module flags inherited by their module-class */ - final val ModuleToClassFlags: Long = AccessFlags | MODULE | PACKAGE | CASE | SYNTHETIC | JAVA | FINAL + final val ModuleToClassFlags: Long = AccessFlags | TopLevelCreationFlags | CASE | SYNTHETIC def getterFlags(fieldFlags: Long): Long = ACCESSOR + ( if ((fieldFlags & MUTABLE) != 0) fieldFlags & ~MUTABLE & ~PRESUPER @@ -407,26 +422,43 @@ class Flags extends ModifierFlags { case _ => "" } - def flagsToString(flags: Long, privateWithin: String): String = { - var f = flags - val pw = - if (privateWithin == "") { - if ((flags & PrivateLocal) == PrivateLocal) { - f &= ~PrivateLocal - "private[this]" - } else if ((flags & ProtectedLocal) == ProtectedLocal) { - f &= ~ProtectedLocal - "protected[this]" - } else { - "" + def accessString(flags: Long, privateWithin: String)= ( + if (privateWithin == "") { + if ((flags & PrivateLocal) == PrivateLocal) "private[this]" + else if ((flags & ProtectedLocal) == ProtectedLocal) "protected[this]" + else if ((flags & PRIVATE) != 0) "private" + else if ((flags & PROTECTED) != 0) "protected" + else "" + } + else if ((flags & PROTECTED) != 0) "protected[" + privateWithin + "]" + else "private[" + privateWithin + "]" + ) + def nonAccessString(flags0: Long)(flagStringFn: Long => String): String = { + val flags = flags0 & ~AccessFlags + // Fast path for common case + if (flags == 0L) "" else { + var sb: StringBuilder = null + var i = 0 + while (i <= MaxBitPosition) { + val mask = rawFlagPickledOrder(i) + if ((flags & mask) != 0L) { + val s = flagStringFn(mask) + if (s.length > 0) { + if (sb eq null) sb = new StringBuilder append s + else if (sb.length == 0) sb append s + else sb append " " append s + } } - } else if ((f & PROTECTED) != 0L) { - f &= ~PROTECTED - "protected[" + privateWithin + "]" - } else { - "private[" + privateWithin + "]" + i += 1 } - List(flagsToString(f), pw) filterNot (_ == "") mkString " " + if (sb eq null) "" else sb.toString + } + } + + def flagsToString(flags: Long, privateWithin: String): String = { + val access = accessString(flags, privateWithin) + val nonAccess = flagsToString(flags & ~AccessFlags) + List(nonAccess, access) filterNot (_ == "") mkString " " } // List of the raw flags, in pickled order diff --git a/src/compiler/scala/reflect/internal/HasFlags.scala b/src/compiler/scala/reflect/internal/HasFlags.scala index 8affd66cd5..2f574b6bfa 100644 --- a/src/compiler/scala/reflect/internal/HasFlags.scala +++ b/src/compiler/scala/reflect/internal/HasFlags.scala @@ -1,76 +1,6 @@ package scala.reflect package internal -/** ISSUE #1: Flag names vs. Test method names - * - * The following methods from Symbol have a name of - * the form isFoo where FOO is the name of a flag, but where the method - * body tests for more than whether the flag is set. - * - * There are two possibilities with such methods. Either the extra - * tests are strictly to partition among overloaded flags (which is - * the case we can live with in the short term, if each such flag's - * partitioning assumptions are documented) or they aren't. - * - * The second case implies that "x hasFlag FOO" and "x.isFoo" have - * different semantics, and this we can't live with, because even if - * we're smart enough to avoid being tripped up by that, the next guy isn't. - * - * No extreme measures necessary, only renaming isFoo to something - * which hews more closely to its implementation. (Or renaming the flag.) - * - // Defined in the compiler Symbol - // - final def isLabel = isMethod && !hasAccessorFlag && hasFlag(LABEL) - final def isLocal: Boolean = owner.isTerm - final def isModuleVar: Boolean = isVariable && hasFlag(MODULEVAR) - final def isStable = - isTerm && - !hasTraitFlag && - (!hasFlag(METHOD | BYNAMEPARAM) || hasFlag(STABLE)) && - !(tpe.isVolatile && !hasAnnotation(uncheckedStableClass)) - final def isStatic: Boolean = - hasFlag(STATIC) || isRoot || owner.isStaticOwner - override final def isTrait: Boolean = - isClass && hasFlag(TRAIT | notDEFERRED) // A virtual class becomes a trait (part of DEVIRTUALIZE) - - // Defined in the library Symbol - // - def isTrait: Boolean = isClass && hasFlag(TRAIT) // refined later for virtual classes. - final def isContravariant = isType && hasFlag(CONTRAVARIANT) - final def isCovariant = isType && hasFlag(COVARIANT) - final def isMethod = isTerm && hasFlag(METHOD) - final def isModule = isTerm && hasFlag(MODULE) - final def isPackage = isModule && hasFlag(PACKAGE) - * - */ - -/** ISSUE #2: Implicit flag relationships must be made explicit. - * - * For instance, every time the MODULE flag is set, the FINAL flag is - * set along with it: - * - .setFlag(FINAL | MODULE | PACKAGE | JAVA) - .setFlag(FINAL | MODULE | PACKAGE | JAVA).setInfo(rootLoader) - new ModuleSymbol(this, pos, name).setFlag(MODULE | FINAL) - new ModuleSymbol(this, pos, name).setFlag(MODULE | FINAL) - val m = new ModuleSymbol(this, pos, name).setFlag(MODULE | FINAL) - setFlag(module.getFlag(ModuleToClassFlags) | MODULE | FINAL) - sourceModule.flags = MODULE | FINAL - - * However the same is not true of when the MODULE flag is cleared: - - sym.resetFlag(MODULE) - .setFlag(sym.flags | STABLE).resetFlag(MODULE) - sym.resetFlag(MODULE | FINAL | CASE) - - * It's not relevant whether this example poses any issues: we must - * not tolerate these uncertainties. If the flags are to move together - * then both setting and clearing have to be encapsulated. If there - * is a useful and used distinction between the various permutations - * of on and off, then it must be documented. It's the only way! - */ - import Flags._ /** Common code utilized by Modifiers (which carry the flags associated @@ -165,26 +95,20 @@ trait HasFlags { // which must have been a bug. def isPublic = hasNoFlags(PRIVATE | PROTECTED) && !hasAccessBoundary - // Renamed the Modifiers impl from isArgument. - def isParameter = hasFlag(PARAM) - // Removed isClass qualification since the flag isn't overloaded and // sym.isClass is enforced in Namers#validate. def isSealed = hasFlag(SEALED) // Removed !isClass qualification since the flag isn't overloaded. - def isDeferred = hasFlag(DEFERRED ) + def isDeferred = hasFlag(DEFERRED) // Dropped isTerm condition because flag isn't overloaded. def isAbstractOverride = hasFlag(ABSOVERRIDE) def isAnyOverride = hasFlag(OVERRIDE | ABSOVERRIDE) - def isDefaultInit = hasFlag(DEFAULTINIT) // Disambiguating: DEFAULTPARAM, TRAIT def hasDefault = hasAllFlags(DEFAULTPARAM | PARAM) def isTrait = hasFlag(TRAIT) && !hasFlag(PARAM) - def hasTraitFlag = hasFlag(TRAIT) - def hasDefaultFlag = hasFlag(DEFAULTPARAM) // Straightforwardly named accessors already being used differently. // These names are most likely temporary. @@ -193,16 +117,9 @@ trait HasFlags { def hasLocalFlag = hasFlag(LOCAL) def hasModuleFlag = hasFlag(MODULE) def hasPackageFlag = hasFlag(PACKAGE) - def hasPreSuperFlag = hasFlag(PRESUPER) def hasStableFlag = hasFlag(STABLE) def hasStaticFlag = hasFlag(STATIC) - // Disambiguating: BYNAMEPARAM, CAPTURED, COVARIANT. - def isByNameParam = hasAllFlags(BYNAMEPARAM | PARAM) - // Nope, these aren't going to fly: - // def isCapturedVariable = hasAllFlags(CAPTURED | MUTABLE) - // def isCovariant = hasFlag(COVARIANT) && hasNoFlags(PARAM | MUTABLE) - // Disambiguating: LABEL, CONTRAVARIANT, INCONSTRUCTOR def isLabel = hasAllFlags(LABEL | METHOD) && !hasAccessorFlag // Cannot effectively disambiguate the others at this level. @@ -212,23 +129,13 @@ trait HasFlags { // Name def isJavaDefined = hasFlag(JAVA) - // Keeping some potentially ambiguous names around so as not to break - // the rest of the world + // Backward compat section + @deprecated( "Use isTrait", "2.10.0") + def hasTraitFlag = hasFlag(TRAIT) + @deprecated("Use hasDefault", "2.10.0") + def hasDefaultFlag = hasFlag(DEFAULTPARAM) @deprecated("", "2.9.0") def isAbstract = hasFlag(ABSTRACT) - // Problematic: - // ABSTRACT and DEFERRED too easy to confuse, and - // ABSTRACT + OVERRIDE ==> ABSOVERRIDE adds to it. - // - // final def isAbstractClass = isClass && hasFlag(ABSTRACT) - // def isAbstractType = false // to be overridden - - // Question: - // Which name? All other flags are isFlag so it's probably a mistake to - // vary from that, but isAccessor does sound like it includes the other - // *ACCESSOR flags. Perhaps something like isSimpleAccessor. - // - // def isAccessor = hasFlag(ACCESSOR ) - // final def isGetterOrSetter = hasAccessorFlag + @deprecated("Use isValueParameter or isTypeParameter", "2.10.0") + def isParameter = hasFlag(PARAM) } - diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala index 04381937d1..5dcff804a8 100644 --- a/src/compiler/scala/reflect/internal/Importers.scala +++ b/src/compiler/scala/reflect/internal/Importers.scala @@ -63,7 +63,7 @@ trait Importers { self: SymbolTable => } myowner.newTypeSkolemSymbol(myname.toTypeName, origin, mypos, myflags) case x: from.ModuleClassSymbol => - val mysym = myowner.newModuleClassSymbol(myname.toTypeName, mypos, myflags) + val mysym = myowner.newModuleClass(myname.toTypeName, mypos, myflags) symMap(x) = mysym mysym.sourceModule = importSymbol(x.sourceModule) mysym @@ -109,14 +109,18 @@ trait Importers { self: SymbolTable => val owner = sym.owner var scope = if (owner.isClass && !owner.isRefinementClass) owner.info else from.NoType var existing = scope.decl(name) - if (sym.isPackageClass || sym.isModuleClass) existing = existing.moduleClass + if (sym.isModuleClass) + existing = existing.moduleClass + if (!existing.exists) scope = from.NoType val myname = importName(name) val myowner = importSymbol(owner) val myscope = if (scope != from.NoType && !(myowner hasFlag Flags.LOCKED)) myowner.info else NoType var myexisting = if (myscope != NoType) myowner.info.decl(myname) else NoSymbol // cannot load myexisting in general case, because it creates cycles for methods - if (sym.isPackageClass || sym.isModuleClass) myexisting = importSymbol(sym.sourceModule).moduleClass + if (sym.isModuleClass) + myexisting = importSymbol(sym.sourceModule).moduleClass + if (!sym.isOverloaded && myexisting.isOverloaded) { myexisting = if (sym.isMethod) { diff --git a/src/compiler/scala/reflect/internal/SymbolCreations.scala b/src/compiler/scala/reflect/internal/SymbolCreations.scala new file mode 100644 index 0000000000..62fee9d7f3 --- /dev/null +++ b/src/compiler/scala/reflect/internal/SymbolCreations.scala @@ -0,0 +1,106 @@ + /* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.reflect +package internal + +import scala.collection.{ mutable, immutable } +import scala.collection.mutable.ListBuffer +import util.Statistics._ +import Flags._ +import api.Modifier +import scala.tools.util.StringOps.{ ojoin } + +trait SymbolCreations { + self: SymbolTable => + + import definitions._ + + /** Symbol creation interface, possibly better moved somewhere else. + * It'd be nice if we had virtual classes, but since we + * don't: these methods insulate the direct instantiation of the symbols + * (which may be overridden, e.g. in SynchronizedSymbols) from the + * enforcement of preconditions and choice of symbol constructor based + * on flags, which are (or should be) final so they can be reasoned about + * without lots of surprises. + */ + trait SymbolCreatorInterface { + // Fallbacks; more precise creators should normally be called. + protected def createTypeSymbol(name: TypeName, pos: Position, newFlags: Long): TypeSymbol + protected def createTermSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol + + // I believe all but rogue TypeSymbols are one of: ClassSymbol, AbstractTypeSymbol, AliasTypeSymbol, or TypeSkolem. + protected def createAbstractTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AbstractTypeSymbol + protected def createAliasTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AliasTypeSymbol + protected def createTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position, newFlags: Long): TypeSkolem + protected def createClassSymbol(name: TypeName, pos: Position, newFlags: Long): ClassSymbol + + // More specific ClassSymbols. + // TODO - AnonymousClassSymbol. + // TODO maybe - PackageObjects, but that one cost me a lot of time when I tried it before + // because it broke reification some way I couldn't see. + protected def createModuleClassSymbol(name: TypeName, pos: Position, newFlags: Long): ModuleClassSymbol + protected def createPackageClassSymbol(name: TypeName, pos: Position, newFlags: Long): PackageClassSymbol + protected def createRefinementClassSymbol(pos: Position, newFlags: Long): RefinementClassSymbol + + // Distinguished term categories include methods, modules, packages, package objects, + // value parameters, and values (including vals, vars, and lazy vals.) + protected def createMethodSymbol(name: TermName, pos: Position, newFlags: Long): MethodSymbol + protected def createModuleSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol + protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): PackageSymbol + + // TODO + // protected def createValueParameterSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol + // protected def createValueMemberSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol + } + + trait SymbolCreator extends SymbolCreatorInterface { + self: Symbol => + + /*** Predictable symbol creation. + * + * newTermSymbol, newClassSymbol, and newNonClassSymbol all create symbols based + * only on the flags (for reconstruction after reification.) It would be nice to + * combine the last two into newTypeSymbol, but this requires some flag which allows us + * to distinguish classes and type aliases, which as yet does not exist. + * + * The fundamental flags used to determine which Symbol subclass to instantiate are: + * METHOD, PACKAGE, MODULE, PARAM, DEFERRED. + */ + final def newTermSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): TermSymbol = { + if ((newFlags & METHOD) != 0) + createMethodSymbol(name, pos, newFlags) + else if ((newFlags & PACKAGE) != 0) + createPackageSymbol(name, pos, newFlags | PackageFlags) + else if ((newFlags & MODULE) != 0) + createModuleSymbol(name, pos, newFlags) + else if ((newFlags & PARAM) != 0) + createValueParameterSymbol(name, pos, newFlags) + else + createValueMemberSymbol(name, pos, newFlags) + } + + final def newClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol = { + if (name == tpnme.REFINE_CLASS_NAME) + createRefinementClassSymbol(pos, newFlags) + else if ((newFlags & PACKAGE) != 0) + createPackageClassSymbol(name, pos, newFlags | PackageFlags) + else if ((newFlags & MODULE) != 0) + createModuleClassSymbol(name, pos, newFlags) + else + createClassSymbol(name, pos, newFlags) + } + + final def newNonClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol = { + if ((newFlags & DEFERRED) != 0) + createAbstractTypeSymbol(name, pos, newFlags) + else + createAliasTypeSymbol(name, pos, newFlags) + } + + def newTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol = + newNonClassSymbol(name, pos, newFlags) + } +} diff --git a/src/compiler/scala/reflect/internal/SymbolFlags.scala b/src/compiler/scala/reflect/internal/SymbolFlags.scala new file mode 100644 index 0000000000..0b49ee2505 --- /dev/null +++ b/src/compiler/scala/reflect/internal/SymbolFlags.scala @@ -0,0 +1,237 @@ + /* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.reflect +package internal + +import scala.collection.{ mutable, immutable } +import scala.collection.mutable.ListBuffer +import util.Statistics._ +import Flags._ +import api.Modifier +import scala.tools.util.StringOps.{ ojoin } + +trait SymbolFlags { + self: SymbolTable => + + import definitions._ + + /** Not mixed in under normal conditions; a powerful debugging aid. + */ + trait FlagVerifier extends SymbolFlagLogic { + this: Symbol => + + private def assert0(cond: Boolean, message: => Any) { + if (!cond) { + Console.err.println("[flag verification failure]\n%s\n%s\n".format(atPhaseStackMessage, message)) + (new Throwable).getStackTrace.take(13).drop(3).foreach(println) + println("") + } + } + + protected def verifyChange(isAdd: Boolean, mask: Long, before: Long) { + val after = if (isAdd) before | mask else before & ~mask + val added = after & ~before + val removed = before & ~after + val ignored = mask & ~added & ~removed + val error = ( + (added & OverloadedFlagsMask) != 0 || (removed & OverloadedFlagsMask) != 0 + // || (ignored != 0) + ) + val addString = if (added == 0) "" else "+(" + flagsToString(added) + ")" + val removeString = if (removed == 0) "" else "-(" + flagsToString(removed) + ")" + val changeString = if (added == 0 && removed == 0) "no change" else addString + " " + removeString + + if (error) { + val templ = ( + """| symbol: %s %s in %s + | call: %s(%s) + | flags: %s + | result: %s""".stripMargin + ) + + assert0(false, templ.format( + shortSymbolClass, + name.decode, + owner, + if (isAdd) "+" else "-", + flagsToString(mask), + flagsToString(before), + changeString + )) + } + } + + protected def verifyFlags(what: String) { + assert0(this hasAllFlags alwaysHasFlags, symbolCreationString + "\n always=%s, what=%s\n".format(flagsToString(alwaysHasFlags), what)) + if (this hasFlag neverHasFlags) { + val hasRaw = (rawflags & neverHasFlags) != 0 + assert0(!hasRaw, symbolCreationString + "\n never=%s, what=%s".format(flagsToString(neverHasFlags), what)) + } + } + override def initFlags(mask: Long): this.type = { + super.initFlags(mask) + verifyFlags("initFlags(" + flagsToString(mask) + ")") + this + } + override def setFlag(mask: Long): this.type = { + verifyChange(true, mask, rawflags) + super.setFlag(mask) + verifyFlags("setFlag(" + flagsToString(mask) + ")") + this + } + override def resetFlag(mask: Long): this.type = { + verifyChange(false, mask, rawflags) + super.resetFlag(mask) + verifyFlags("resetFlag(" + flagsToString(mask) + ")") + this + } + override def flags_=(fs: Long) { + if ((fs & ~rawflags) != 0) + verifyChange(true, fs & ~rawflags, rawflags) + if ((rawflags & ~fs) != 0) + verifyChange(false, rawflags & ~fs, rawflags) + + super.flags_=(fs) + verifyFlags("flags_=(" + flagsToString(fs) + ")") + } + } + + /** A distinguishing flag is one which the mixing class must always + * have, and which no other symbol class is allowed to have. + */ + trait DistinguishingFlag extends SymbolFlagLogic { + this: Symbol => + + def distinguishingFlag: Long + override protected def alwaysHasFlags = super.alwaysHasFlags | distinguishingFlag + override protected def neverHasFlags = super.neverHasFlags & ~distinguishingFlag + } + + trait SymbolFlagLogic { + this: Symbol => + + protected def alwaysHasFlags: Long = 0L + protected def neverHasFlags: Long = METHOD | MODULE + + def flagStringFn(flag: Long): String = { + val res = flag match { + // "<bynameparam/captured/covariant>" + case BYNAMEPARAM => + if (this.isValueParameter) "<bynameparam>" + else if (this.isTypeParameter) "<covariant>" + else "<captured>" + // "<contravariant/inconstructor/label>" + case CONTRAVARIANT => + if (this.isLabel) "<label>" + else if (this.isTypeParameter) "<contravariant>" + else "<inconstructor>" + // "<defaultparam/trait>" + case DEFAULTPARAM => + if (this.isTerm && (this hasFlag PARAM)) "<defaultparam>" + else "<trait>" + // "<existential/mixedin>" + case EXISTENTIAL => + if (this.isType) "<existential>" + else "<mixedin>" + // "<implclass/presuper>" + case IMPLCLASS => + if (this.isClass) "<implclass>" + else "<presuper>" + case _ => "" + } + if (res == "") Flags.flagToString(flag) + else res + ":overloaded-flag" + } + + private def calculateFlagString(basis: Long): String = { + val nonAccess = nonAccessString(basis)(flagStringFn) + val access = Flags.accessString(basis, pwString) + + ojoin(nonAccess, access) + } + + def flagString(mask: Long): String = calculateFlagString(flags & mask) + def flagString: String = flagString(defaultFlagMask) + def rawFlagString(mask: Long): String = calculateFlagString(rawflags & mask) + def rawFlagString: String = rawFlagString(defaultFlagMask) + def flaggedString(mask: Long): String = flagString(mask) + def flaggedString: String = flaggedString(defaultFlagMask) + + def accessString = calculateFlagString(flags & AccessFlags) + def debugFlagString = flaggedString(AllFlags) + def defaultFlagString = flaggedString(defaultFlagMask) + + def hasFlagsToString(mask: Long) = flagString(mask) + + /** String representation of symbol's variance */ + def varianceString: String = + if (variance == 1) "+" + else if (variance == -1) "-" + else "" + + def defaultFlagMask = + if (settings.debug.value && !isAbstractType) AllFlags + else if (owner.isRefinementClass) ExplicitFlags & ~OVERRIDE + else ExplicitFlags + + // make the error message more googlable + def flagsExplanationString = + if (isGADTSkolem) " (this is a GADT skolem)" + else "" + + private def pwString = if (hasAccessBoundary) privateWithin.toString else "" + private var _rawflags: FlagsType = 0L + protected def rawflags_=(x: FlagsType) { _rawflags = x } + def rawflags = _rawflags + + final def flags: Long = { + val fs = rawflags & phase.flagMask + (fs | ((fs & LateFlags) >>> LateShift)) & ~(fs >>> AntiShift) + } + def flags_=(fs: Long) = rawflags = fs + + /** Set the symbol's flags to the given value, asserting + * that the previous value was 0. + */ + def initFlags(mask: Long): this.type = { + assert(rawflags == 0L, symbolCreationString) + rawflags = mask + this + } + def reinitFlags(mask: Long): this.type = { + rawflags = mask + this + } + def setFlag(mask: Long): this.type = { rawflags |= mask ; this } + def resetFlag(mask: Long): this.type = { rawflags &= ~mask ; this } + def resetFlags() { rawflags &= (TopLevelCreationFlags | alwaysHasFlags) } + + def getFlag(mask: Long): Long + def hasFlag(mask: Long): Boolean + def hasAllFlags(mask: Long): Boolean + + /** If the given flag is set on this symbol, also set the corresponding + * notFLAG. For instance if flag is PRIVATE, the notPRIVATE flag will + * be set if PRIVATE is currently set. + */ + final def setNotFlag(flag: Int) = if (hasFlag(flag)) setFlag((flag: @annotation.switch) match { + case PRIVATE => notPRIVATE + case PROTECTED => notPROTECTED + case OVERRIDE => notOVERRIDE + case _ => abort("setNotFlag on invalid flag: " + flag) + }) + + protected def shortSymbolClass = getClass.getName.split('.').last.stripPrefix("Symbols$") + def symbolCreationString: String = ( + "%s%25s | %-40s | %s".format( + if (settings.uniqid.value) "%06d | ".format(id) else "", + shortSymbolClass, + name.decode + " in " + owner, + rawFlagString + ) + ) + } +} diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala index 256c1a6ced..daaf0dff26 100644 --- a/src/compiler/scala/reflect/internal/SymbolTable.scala +++ b/src/compiler/scala/reflect/internal/SymbolTable.scala @@ -13,7 +13,9 @@ import scala.tools.nsc.util.WeakHashSet abstract class SymbolTable extends api.Universe with Collections with Names + with SymbolCreations with Symbols + with SymbolFlags with Types with Kinds with ExistentialsAndSkolems @@ -62,6 +64,8 @@ abstract class SymbolTable extends api.Universe result } + /** Dump each symbol to stdout after shutdown. + */ final val traceSymbolActivity = sys.props contains "scalac.debug.syms" object traceSymbols extends { val global: SymbolTable.this.type = SymbolTable.this @@ -98,6 +102,11 @@ abstract class SymbolTable extends api.Universe final def atPhaseStack: List[Phase] = phStack final def phase: Phase = ph + def atPhaseStackMessage = atPhaseStack match { + case Nil => "" + case ps => ps.reverseMap("->" + _).mkString("(", " ", ")") + } + final def phase_=(p: Phase) { //System.out.println("setting phase to " + p) assert((p ne null) && p != NoPhase, p) diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 63d030531d..dc72ac2338 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -55,11 +55,14 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ val originalOwner = perRunCaches.newMap[Symbol, Symbol]() - abstract class AbsSymbolImpl extends AbsSymbol { this: Symbol => - def newNestedSymbol(name: Name, pos: Position, newFlags: Long) = name match { + abstract class AbsSymbolImpl extends AbsSymbol { + this: Symbol => + + def newNestedSymbol(name: Name, pos: Position, newFlags: Long, isClass: Boolean): Symbol = name match { case n: TermName => newTermSymbol(n, pos, newFlags) - case n: TypeName => newTypeSymbol(n, pos, newFlags) + case n: TypeName => if (isClass) newClassSymbol(n, pos, newFlags) else newNonClassSymbol(n, pos, newFlags) } + def enclosingClass: Symbol = enclClass def enclosingMethod: Symbol = enclMethod def thisPrefix: Type = thisType @@ -146,6 +149,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => abstract class Symbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: Name) extends AbsSymbolImpl with HasFlags + with SymbolFlagLogic + with SymbolCreator + // with FlagVerifier with Annotatable[Symbol] { type FlagsType = Long @@ -154,13 +160,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => private[this] var _rawowner = initOwner // Syncnote: need not be protected, as only assignment happens in owner_=, which is not exposed to api private[this] var _rawname = initName - private[this] var _rawflags = 0L def rawowner = _rawowner def rawname = _rawname - def rawflags = _rawflags - - protected def rawflags_=(x: FlagsType) { _rawflags = x } private var rawpos = initPos @@ -202,7 +204,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def newLocalDummy(pos: Position) = newTermSymbol(nme.localDummyName(this), pos) setInfo NoType final def newMethod(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): MethodSymbol = - newMethodSymbol(name, pos, METHOD | newFlags) + createMethodSymbol(name, pos, METHOD | newFlags) final def newLabel(name: TermName, pos: Position = NoPosition): MethodSymbol = newMethod(name, pos, LABEL) @@ -213,73 +215,39 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Static constructor with info set. */ def newStaticConstructor(pos: Position) = newConstructor(pos, STATIC) setInfo UnitClass.tpe + /** Instance constructor with info set. */ def newClassConstructor(pos: Position) = newConstructor(pos) setInfo MethodType(Nil, this.tpe) - // Top-level objects can be automatically marked final, but others - // must be explicitly marked final if overridable objects are enabled. - private def ModuleFlags = ( - if (isPackage || !settings.overrideObjects.value) MODULE | FINAL - else MODULE - ) def newLinkedModule(clazz: Symbol, newFlags: Long = 0L): ModuleSymbol = { - val m = newModuleSymbol(clazz.name.toTermName, clazz.pos, ModuleFlags | newFlags) + val m = newModuleSymbol(clazz.name.toTermName, clazz.pos, MODULE | newFlags) connectModuleToClass(m, clazz.asInstanceOf[ClassSymbol]) } final def newModule(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol = { - val m = newModuleSymbol(name, pos, newFlags | ModuleFlags) - val clazz = newModuleClassSymbol(name.toTypeName, pos, (m getFlag ModuleToClassFlags) | MODULE) + val m = newModuleSymbol(name, pos, newFlags | MODULE) + val clazz = newModuleClass(name.toTypeName, pos, m getFlag ModuleToClassFlags) connectModuleToClass(m, clazz) } final def newPackage(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol = { assert(name == nme.ROOT || isPackageClass, this) - newModule(name, pos, JAVA | PACKAGE | newFlags) + newModule(name, pos, PackageFlags | newFlags) } + final def newThisSym(pos: Position) = newTermSymbol(nme.this_, pos, SYNTHETIC) final def newImport(pos: Position) = newTermSymbol(nme.IMPORT, pos) - /** Direct symbol factories. - * For internal use; these are unlikely to be what you want. - */ - def newTermSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): TermSymbol = - new TermSymbol(this, pos, name) initFlags newFlags + final def newModuleSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol = + newTermSymbol(name, pos, newFlags).asInstanceOf[ModuleSymbol] - def newAbstractTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): AbstractTypeSymbol = - new AbstractTypeSymbol(this, pos, name) initFlags newFlags + final def newModuleClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleClassSymbol = + newClassSymbol(name, pos, newFlags).asInstanceOf[ModuleClassSymbol] - def newAliasTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): AliasTypeSymbol = - new AliasTypeSymbol(this, pos, name) initFlags newFlags - - def newModuleSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol = - new ModuleSymbol(this, pos, name) initFlags newFlags - - def newMethodSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): MethodSymbol = - new MethodSymbol(this, pos, name) initFlags newFlags - - def newClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol = - new ClassSymbol(this, pos, name) initFlags newFlags - - def newModuleClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleClassSymbol = - new ModuleClassSymbol(this, pos, name) initFlags newFlags - - /** Derive whether it is an abstract type from the flags; after creation - * the DEFERRED flag will be ignored. - */ - def newTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol = - if ((newFlags & DEFERRED) == 0L) - newAliasTypeSymbol(name, pos, newFlags) - else - newAbstractTypeSymbol(name, pos, newFlags) - - def newTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position = NoPosition, newFlags: Long = 0L): TypeSkolem = - if ((newFlags & DEFERRED) == 0L) - new TypeSkolem(this, pos, name, origin) initFlags newFlags - else - new TypeSkolem(this, pos, name, origin) with AbstractTypeMixin initFlags newFlags + final def newTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position = NoPosition, newFlags: Long = 0L): TypeSkolem = + createTypeSkolemSymbol(name, origin, pos, newFlags) /** @param pre type relative to which alternatives are seen. * for instance: @@ -310,18 +278,23 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Symbol of a type definition type T = ... */ final def newAliasType(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): Symbol = - newAliasTypeSymbol(name, pos, newFlags) + createAliasTypeSymbol(name, pos, newFlags) /** Symbol of an abstract type type T >: ... <: ... */ final def newAbstractType(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): Symbol = - newAbstractTypeSymbol(name, pos, DEFERRED | newFlags) + createAbstractTypeSymbol(name, pos, DEFERRED | newFlags) /** Symbol of a type parameter */ final def newTypeParameter(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L) = newAbstractType(name, pos, PARAM | newFlags) + /** Symbol of an existential type T forSome { ... } + */ + final def newExistential(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): Symbol = + newAbstractType(name, pos, EXISTENTIAL | newFlags) + /** Synthetic value parameters when parameter symbols are not available */ final def newSyntheticValueParamss(argtypess: List[List[Type]]): List[List[Symbol]] = { @@ -347,10 +320,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => def newGADTSkolem(name: TypeName, origin: Symbol, info: Type): TypeSkolem = newTypeSkolemSymbol(name, origin, origin.pos, origin.flags & ~(EXISTENTIAL | PARAM) | CASEACCESSOR | SYNTHETIC) setInfo info - - final def newExistential(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): Symbol = - newAbstractType(name, pos, EXISTENTIAL | newFlags) - final def freshExistential(suffix: String): Symbol = newExistential(freshExistentialName(suffix), pos) @@ -385,8 +354,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def newErrorClass(name: TypeName) = newClassWithInfo(name, Nil, new ErrorScope(this), pos, SYNTHETIC | IS_ERROR) - final def newModuleClass(name: TypeName, pos: Position = NoPosition) = - newModuleClassSymbol(name, pos) + final def newModuleClass(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L) = + newModuleClassSymbol(name, pos, newFlags | MODULE) final def newAnonymousClass(pos: Position) = newClassSymbol(tpnme.ANON_CLASS_NAME, pos) @@ -400,8 +369,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Refinement types P { val x: String; type T <: Number } * also have symbols, they are refinementClasses */ - final def newRefinementClass(pos: Position) = - newClass(tpnme.REFINE_CLASS_NAME, pos) + final def newRefinementClass(pos: Position) = createRefinementClassSymbol(pos, 0L) /** Create a new getter for current symbol (which must be a field) */ @@ -477,7 +445,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => if ((rawflags & LOCKED) != 0L) { // activeLocks -= 1 // lockedSyms -= this - _rawflags = rawflags & ~LOCKED + rawflags &= ~LOCKED if (settings.Yrecursion.value != 0) recursionTable -= this } @@ -485,42 +453,84 @@ trait Symbols extends api.Symbols { self: SymbolTable => // ----- tests ---------------------------------------------------------------------- - def isTerm = false // to be overridden - def isType = false // to be overridden - def isClass = false // to be overridden - def isBottomClass = false // to be overridden - def isAliasType = false // to be overridden - def isAbstractType = false // to be overridden - private[scala] def isSkolem = false // to be overridden - - /** Is this symbol a type but not a class? */ - def isNonClassType = false // to be overridden - - override final def isTrait = isClass && hasFlag(TRAIT) - final def isAbstractClass = isClass && hasFlag(ABSTRACT) - final def isBridge = hasFlag(BRIDGE) - final def isContravariant = isType && hasFlag(CONTRAVARIANT) - final def isConcreteClass = isClass && !hasFlag(ABSTRACT | TRAIT) - final def isCovariant = isType && hasFlag(COVARIANT) - final def isEarlyInitialized = isTerm && hasFlag(PRESUPER) - final def isExistentiallyBound = isType && hasFlag(EXISTENTIAL) - final def isImplClass = isClass && hasFlag(IMPLCLASS) - final def isLazyAccessor = isLazy && lazyAccessor != NoSymbol - final def isMethod = isTerm && hasFlag(METHOD) - final def isModule = isTerm && hasFlag(MODULE) - final def isModuleClass = isClass && hasFlag(MODULE) - final def isNumericValueClass = definitions.isNumericValueClass(this) - final def isOverloaded = hasFlag(OVERLOADED) - final def isOverridableMember = !(isClass || isEffectivelyFinal) && owner.isClass - final def isRefinementClass = isClass && name == tpnme.REFINE_CLASS_NAME - final def isSourceMethod = isMethod && !hasFlag(STABLE) // exclude all accessors!!! - final def isTypeParameter = isType && isParameter && !isSkolem - final def isPrimitiveValueClass = definitions.isPrimitiveValueClass(this) - final def isVarargsMethod = isMethod && hasFlag(VARARGS) - - /** Package tests */ - final def isPackage = isModule && hasFlag(PACKAGE) - final def isPackageClass = isClass && hasFlag(PACKAGE) + /** All symbols are one of three categories: TermSymbol, TypeSymbol, or NoSymbol. + * There is only one NoSymbol. + */ + def isTerm = false + def isType = false + + /** TypeSymbols fall into four named direct subclasses: + * - ClassSymbol + * - AliasTypeSymbol + * - AbstractTypeSymbol + * - TypeSkolem + */ + def isClass = false + def isAliasType = false + def isAbstractType = false + def isSkolem = false + + /** A Type, but not a Class. */ + def isNonClassType = false + + /** The bottom classes are Nothing and Null, found in Definitions. */ + def isBottomClass = false + + /** These are all tests for varieties of ClassSymbol, which has these subclasses: + * - ModuleClassSymbol + * - RefinementClassSymbol + * - PackageClassSymbol (extends ModuleClassSymbol) + */ + def isAbstractClass = false + def isAnonOrRefinementClass = false + def isAnonymousClass = false + def isConcreteClass = false + def isImplClass = false // the implementation class of a trait + def isModuleClass = false + def isNumericValueClass = false + def isPrimitiveValueClass = false + def isRefinementClass = false + override def isTrait = false + + /** Qualities of Types, always false for TermSymbols. + */ + def isContravariant = false + def isCovariant = false + def isExistentialSkolem = false + def isExistentiallyBound = false + def isExistentialQuantified = false + def isGADTSkolem = false + def isTypeParameter = false + def isTypeParameterOrSkolem = false + def isTypeSkolem = false + + /** Qualities of Terms, always false for TypeSymbols. + */ + override def hasDefault = false + def isBridge = false + def isEarlyInitialized = false + def isModule = false + def isOverloaded = false + def isValueParameter = false + + /** Qualities of MethodSymbols, always false for TypeSymbols + * and other TermSymbols. + */ + def isCaseAccessorMethod = false + def isLiftedMethod = false + def isMacro = false + def isMethod = false + def isSourceMethod = false + def isVarargsMethod = false + + /** Package/package object tests */ + def isPackage = false + def isPackageClass = false + def isPackageObject = false + def isPackageObjectClass = false + + def isPackageObjectOrClass = isPackageObject || isPackageObjectClass + def isModuleOrModuleClass = isModule || isModuleClass /** Overridden in custom objects in Definitions */ def isRoot = false @@ -533,22 +543,30 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ def isEffectiveRoot = false - /** For RootClass, EmptyPackageClass. For all other symbols, itself. + /** For RootClass, this is EmptyPackageClass. For all other symbols, + * the symbol itself. */ def ownerOfNewSymbols = this + final def isLazyAccessor = isLazy && lazyAccessor != NoSymbol + final def isOverridableMember = !(isClass || isEffectivelyFinal) && owner.isClass + /** Does this symbol denote a wrapper created by the repl? */ final def isInterpreterWrapper = ( - (isModule || isModuleClass) + (this hasFlag MODULE) && owner.isPackageClass && nme.isReplWrapperName(name) ) + @inline final override def getFlag(mask: Long): Long = flags & mask + /** Does symbol have ANY flag in `mask` set? */ + @inline final override def hasFlag(mask: Long): Boolean = (flags & mask) != 0 + /** Does symbol have ALL the flags in `mask` set? */ + @inline final override def hasAllFlags(mask: Long): Boolean = (flags & mask) == mask /** Term symbols with the exception of static parts of Java classes and packages. */ - final def isValue = isTerm && !(isModule && hasFlag(PACKAGE | JAVA)) - - final def isVariable = isTerm && isMutable && !isMethod + final def isValue = isTerm && !(isModule && hasFlag(PACKAGE | JAVA)) + final def isVariable = isTerm && isMutable && !isMethod // interesting only for lambda lift. Captured variables are accessed from inner lambdas. final def isCapturedVariable = isVariable && hasFlag(CAPTURED) @@ -560,9 +578,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def hasGetter = isTerm && nme.isLocalName(name) - final def isValueParameter = isTerm && hasFlag(PARAM) - final def isLocalDummy = isTerm && nme.isLocalDummyName(name) final def isInitializedToDefault = !isType && hasAllFlags(DEFAULTINIT | ACCESSOR) + final def isLocalDummy = isTerm && nme.isLocalDummyName(name) final def isClassConstructor = isTerm && (name == nme.CONSTRUCTOR) final def isMixinConstructor = isTerm && (name == nme.MIXIN_CONSTRUCTOR) final def isConstructor = isTerm && nme.isConstructorName(name) @@ -570,17 +587,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isThisSym = isTerm && owner.thisSym == this final def isError = hasFlag(IS_ERROR) final def isErroneous = isError || isInitialized && tpe.isErroneous - final def isTypeParameterOrSkolem = isType && hasFlag(PARAM) - final def isHigherOrderTypeParameter = (this ne NoSymbol) && owner.isTypeParameterOrSkolem - final def isTypeSkolem = isSkolem && hasFlag(PARAM) - // a type symbol bound by an existential type, for instance the T in - // List[T] forSome { type T } - final def isExistentialSkolem = isExistentiallyBound && isSkolem - final def isExistentialQuantified = isExistentiallyBound && !isSkolem - final def isGADTSkolem = isSkolem && hasFlag(CASEACCESSOR | SYNTHETIC) + + def isHigherOrderTypeParameter = owner.isTypeParameterOrSkolem // class C extends D( { class E { ... } ... } ). Here, E is a class local to a constructor - final def isClassLocalToConstructor = isClass && hasFlag(INCONSTRUCTOR) + def isClassLocalToConstructor = false final def isDerivedValueClass = isClass && info.firstParent.typeSymbol == AnyValClass && !isPrimitiveValueClass @@ -588,29 +599,27 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isMethodWithExtension = isMethod && owner.isDerivedValueClass && !isParamAccessor && !isConstructor && !hasFlag(SUPERACCESSOR) - final def isAnonymousClass = isClass && (name containsName tpnme.ANON_CLASS_NAME) - final def isAnonymousFunction = isSynthetic && (name containsName tpnme.ANON_FUN_NAME) - final def isAnonOrRefinementClass = isAnonymousClass || isRefinementClass - - // A package object or its module class - final def isPackageObjectOrClass = (this ne NoSymbol) && owner.isPackageClass && (name == nme.PACKAGE || name == tpnme.PACKAGE) - final def isPackageObject = (this ne NoSymbol) && owner.isPackageClass && name == nme.PACKAGE - final def isPackageObjectClass = (this ne NoSymbol) && owner.isPackageClass && name == tpnme.PACKAGE - + final def isAnonymousFunction = isSynthetic && (name containsName tpnme.ANON_FUN_NAME) final def isDefinedInPackage = effectiveOwner.isPackageClass - final def isJavaInterface = isJavaDefined && isTrait - final def needsFlatClasses = phase.flatClasses && rawowner != NoSymbol && !rawowner.isPackageClass + final def isJavaInterface = isJavaDefined && isTrait + final def needsFlatClasses = phase.flatClasses && rawowner != NoSymbol && !rawowner.isPackageClass + + /** change name by appending $$<fully-qualified-name-of-class `base`> + * Do the same for any accessed symbols or setters/getters. + * Implementation in TermSymbol. + */ + def expandName(base: Symbol) { } // In java.lang, Predef, or scala package/package object def isInDefaultNamespace = UnqualifiedOwners(effectiveOwner) /** The owner, skipping package objects. */ - def effectiveOwner = if (owner.isPackageObjectClass) owner.skipPackageObject else owner + def effectiveOwner = owner.skipPackageObject /** If this is a package object or its implementing class, its owner: otherwise this. */ - final def skipPackageObject: Symbol = if (isPackageObjectOrClass) owner else this + def skipPackageObject: Symbol = if (this.isPackageObjectOrClass) owner else this /** If this is a constructor, its owner: otherwise this. */ @@ -689,15 +698,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => // def isVirtualClass = hasFlag(DEFERRED) && isClass // def isVirtualTrait = hasFlag(DEFERRED) && isTrait - def isLiftedMethod = isMethod && hasFlag(LIFTED) + // def isLiftedMethod = hasAllFlags(METHOD | LIFTED) def isCaseClass = isClass && isCase - // unfortunately having the CASEACCESSOR flag does not actually mean you - // are a case accessor (you can also be a field.) - def isCaseAccessorMethod = isMethod && isCaseAccessor - - def isMacro = isMethod && hasFlag(MACRO) - /** Does this symbol denote the primary constructor of its enclosing class? */ final def isPrimaryConstructor = isConstructor && owner.primaryConstructor == this @@ -742,10 +745,12 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isStaticOwner: Boolean = isPackageClass || isModuleClass && isStatic + def isTopLevelModule = hasFlag(MODULE) && owner.isPackageClass + /** Is this symbol effectively final? I.e, it cannot be overridden */ final def isEffectivelyFinal: Boolean = ( - isFinal - || hasModuleFlag && !settings.overrideObjects.value + (this hasFlag FINAL | PACKAGE) + || isModuleOrModuleClass && (owner.isPackageClass || !settings.overrideObjects.value) || isTerm && ( isPrivate || isLocal @@ -760,7 +765,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isConstant: Boolean = isStable && isConstantType(tpe.resultType) /** Is this class nested in another class or module (not a package)? */ - def isNestedClass = isClass && !owner.isPackageClass + def isNestedClass = false /** Is this class locally defined? * A class is local, if @@ -768,9 +773,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => * - its owner is a value * - it is defined within a local class */ - final def isLocalClass: Boolean = - isClass && (isAnonOrRefinementClass || isLocal || - !owner.isPackageClass && owner.isLocalClass) + def isLocalClass = false + + def isStableClass = false /* code for fixing nested objects override final def isModuleClass: Boolean = @@ -805,26 +810,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => // Does not always work if the rawInfo is a SourcefileLoader, see comment // in "def coreClassesFirst" in Global. - final def exists: Boolean = - this != NoSymbol && (!owner.isPackageClass || { rawInfo.load(this); rawInfo != NoType }) + def exists = !owner.isPackageClass || { rawInfo.load(this); rawInfo != NoType } final def isInitialized: Boolean = validTo != NoPeriod - final def isStableClass: Boolean = { - def hasNoAbstractTypeMember(clazz: Symbol): Boolean = - (clazz hasFlag STABLE) || { - var e = clazz.info.decls.elems - while ((e ne null) && !(e.sym.isAbstractType && info.member(e.sym.name) == e.sym)) - e = e.next - e == null - } - def checkStable() = - (info.baseClasses forall hasNoAbstractTypeMember) && { setFlag(STABLE); true } - isClass && (hasFlag(STABLE) || checkStable()) - } - - /** The variance of this symbol as an integer */ final def variance: Int = if (isCovariant) 1 @@ -855,6 +845,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => // ------ owner attribute -------------------------------------------------------------- def owner: Symbol = rawowner + // TODO - don't allow the owner to be changed without checking invariants, at least + // when under some flag. Define per-phase invariants for owner/owned relationships, + // e.g. after flatten all classes are owned by package classes, there are lots and + // lots of these to be declared (or more realistically, discovered.) def owner_=(owner: Symbol) { // don't keep the original owner in presentation compiler runs // (the map will grow indefinitely, and the only use case is the @@ -872,11 +866,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => def ownerChain: List[Symbol] = this :: owner.ownerChain def originalOwnerChain: List[Symbol] = this :: originalOwner.getOrElse(this, rawowner).originalOwnerChain - def enclClassChain: List[Symbol] = { - if ((this eq NoSymbol) || isPackageClass) Nil - else if (isClass) this :: owner.enclClassChain - else owner.enclClassChain - } + // Non-classes skip self and return rest of owner chain; overridden in ClassSymbol. + def enclClassChain: List[Symbol] = owner.enclClassChain def ownersIterator: Iterator[Symbol] = new Iterator[Symbol] { private var current = Symbol.this @@ -884,21 +875,21 @@ trait Symbols extends api.Symbols { self: SymbolTable => def next = { val r = current; current = current.owner; r } } - /** same as ownerChain contains sym, but more efficient, and - * with a twist for refinement classes. A refinement class - * has a transowner X if an of its parents has transowner X. + /** Same as `ownerChain contains sym` but more efficient, and + * with a twist for refinement classes (see RefinementClassSymbol.) */ def hasTransOwner(sym: Symbol): Boolean = { var o = this while ((o ne sym) && (o ne NoSymbol)) o = o.owner - (o eq sym) || - isRefinementClass && (info.parents exists (_.typeSymbol.hasTransOwner(sym))) + (o eq sym) } // ------ name attribute -------------------------------------------------------------- def name: Name = rawname + // TODO - don't allow names to be renamed in this unstructured a fashion. + // Rename as little as possible. Enforce invariants on all renames. def name_=(name: Name) { if (name != rawname) { if (owner.isClass) { @@ -970,43 +961,50 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ final def fullName: String = fullName('.') -// ------ flags attribute -------------------------------------------------------------- + /** + * Symbol creation implementations. + */ + protected def createTypeSymbol(name: TypeName, pos: Position, newFlags: Long): TypeSymbol = + new TypeSymbol(this, pos, name) { } initFlags newFlags - final def flags: Long = { - val fs = rawflags & phase.flagMask - (fs | ((fs & LateFlags) >>> LateShift)) & ~(fs >>> AntiShift) - } - def flags_=(fs: Long) = _rawflags = fs + protected def createAbstractTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AbstractTypeSymbol = + new AbstractTypeSymbol(this, pos, name) initFlags newFlags - /** Set the symbol's flags to the given value, asserting - * that the previous value was 0. - */ - def initFlags(mask: Long): this.type = { - assert(rawflags == 0L, this) - _rawflags = mask - this - } - def setFlag(mask: Long): this.type = { _rawflags = rawflags | mask ; this } - def resetFlag(mask: Long): this.type = { _rawflags = rawflags & ~mask ; this } - final def getFlag(mask: Long): Long = flags & mask - final def resetFlags() { _rawflags = rawflags & TopLevelCreationFlags } + protected def createAliasTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AliasTypeSymbol = + new AliasTypeSymbol(this, pos, name) initFlags newFlags - /** Does symbol have ANY flag in `mask` set? */ - final def hasFlag(mask: Long): Boolean = (flags & mask) != 0L + protected def createTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position, newFlags: Long): TypeSkolem = + new TypeSkolem(this, pos, name, origin) initFlags newFlags - /** Does symbol have ALL the flags in `mask` set? */ - final def hasAllFlags(mask: Long): Boolean = (flags & mask) == mask + protected def createClassSymbol(name: TypeName, pos: Position, newFlags: Long): ClassSymbol = + new ClassSymbol(this, pos, name) initFlags newFlags - /** If the given flag is set on this symbol, also set the corresponding - * notFLAG. For instance if flag is PRIVATE, the notPRIVATE flag will - * be set if PRIVATE is currently set. - */ - final def setNotFlag(flag: Int) = if (hasFlag(flag)) setFlag((flag: @annotation.switch) match { - case PRIVATE => notPRIVATE - case PROTECTED => notPROTECTED - case OVERRIDE => notOVERRIDE - case _ => abort("setNotFlag on invalid flag: " + flag) - }) + protected def createModuleClassSymbol(name: TypeName, pos: Position, newFlags: Long): ModuleClassSymbol = + new ModuleClassSymbol(this, pos, name) initFlags newFlags + + protected def createPackageClassSymbol(name: TypeName, pos: Position, newFlags: Long): PackageClassSymbol = + new PackageClassSymbol(this, pos, name) initFlags newFlags + + protected def createRefinementClassSymbol(pos: Position, newFlags: Long): RefinementClassSymbol = + new RefinementClassSymbol(this, pos) initFlags newFlags + + protected def createTermSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol = + new TermSymbol(this, pos, name) initFlags newFlags + + protected def createMethodSymbol(name: TermName, pos: Position, newFlags: Long): MethodSymbol = + new MethodSymbol(this, pos, name) initFlags newFlags + + protected def createModuleSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol = + new ModuleSymbol(this, pos, name) initFlags newFlags + + protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): PackageSymbol = + new PackageSymbol(this, pos, name) initFlags newFlags + + protected def createValueParameterSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol = + new TermSymbol(this, pos, name) initFlags newFlags + + protected def createValueMemberSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol = + new TermSymbol(this, pos, name) initFlags newFlags /** The class or term up to which this symbol is accessible, * or RootClass if it is public. As java protected statics are @@ -1075,7 +1073,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => throw CyclicReference(this, tp) } } else { - _rawflags |= LOCKED + rawflags |= LOCKED // activeLocks += 1 // lockedSyms += this } @@ -1258,7 +1256,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => * which immediately follows any of parser, namer, typer, or erasure. * In effect that means this will return one of: * - * - packageobjects (follows namer) + * - packageobjects (follows namer) * - superaccessors (follows typer) * - lazyvals (follows erasure) * - null @@ -1267,9 +1265,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => var ph = phase while (ph.prev.keepsTypeParams) ph = ph.prev - // - // if (ph ne phase) - // debuglog("checking unsafeTypeParams(" + this + ") at: " + phase + " reading at: " + ph) ph } @@ -1301,7 +1296,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** The value parameter sections of this symbol. */ def paramss: List[List[Symbol]] = info.paramss - def hasParamWhich(cond: Symbol => Boolean) = paramss exists (_ exists cond) + def hasParamWhich(cond: Symbol => Boolean) = mexists(paramss)(cond) /** The least proper supertype of a class; includes all parent types * and refinement where needed. You need to compute that in a situation like this: @@ -1499,7 +1494,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Internal method to clone a symbol's implementation with the given flags and no info. */ def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol - def cloneSymbolImpl(owner: Symbol): Symbol = cloneSymbolImpl(owner, 0L) // ------ access to related symbols -------------------------------------------------- @@ -1510,14 +1504,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => def enclMethod: Symbol = if (isSourceMethod) this else owner.enclMethod /** The primary constructor of a class. */ - def primaryConstructor: Symbol = { - var c = info.decl( - if (isTrait || isImplClass) nme.MIXIN_CONSTRUCTOR - else nme.CONSTRUCTOR) - c = if (c hasFlag OVERLOADED) c.alternatives.head else c - //assert(c != NoSymbol) - c - } + def primaryConstructor: Symbol = NoSymbol /** The self symbol (a TermSymbol) of a class with explicit self type, or else the * symbol itself (a TypeSymbol). @@ -1574,6 +1561,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => * is not updated when a module is cloned), or NoSymbol if this is not a ModuleClass. */ def sourceModule: Symbol = NoSymbol + // if (isModuleClass) companionModule else NoSymbol + // NoSymbol /** The implementation class of a trait. If available it will be the * symbol with the same owner, and the name of this symbol with $class @@ -1627,13 +1616,12 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** The package class containing this symbol, or NoSymbol if there * is not one. */ - def enclosingPackageClass: Symbol = - if (this == NoSymbol) this else { - var packSym = this.owner - while (packSym != NoSymbol && !packSym.isPackageClass) - packSym = packSym.owner - packSym - } + def enclosingPackageClass: Symbol = { + var packSym = this.owner + while (packSym != NoSymbol && !packSym.isPackageClass) + packSym = packSym.owner + packSym + } /** The package containing this symbol, or NoSymbol if there * is not one. */ @@ -1744,21 +1732,12 @@ trait Symbols extends api.Symbols { self: SymbolTable => * Note: does not work for classes owned by methods, see Namers.companionClassOf * * object Foo . companionClass --> class Foo + * + * !!! linkedClassOfClass depends on companionClass on the module class getting + * to the class. As presently implemented this potentially returns class for + * any symbol except NoSymbol. */ - final def companionClass: Symbol = { - if (this != NoSymbol) - flatOwnerInfo.decl(name.toTypeName).suchThat(_ isCoDefinedWith this) - else NoSymbol - } - - /** A helper method that factors the common code used the discover a - * companion module of a class. If a companion module exists, its symbol is - * returned, otherwise, `NoSymbol` is returned. The method assumes that - * `this` symbol has already been checked to be a class (using `isClass`). - */ - private final def companionModule0: Symbol = - flatOwnerInfo.decl(name.toTermName).suchThat( - sym => sym.hasFlag(MODULE) && (sym isCoDefinedWith this) && !sym.isMethod) + def companionClass: Symbol = flatOwnerInfo.decl(name.toTypeName).suchThat(_ isCoDefinedWith this) /** For a class: the module or case class factory with the same name in the same package. * For all others: NoSymbol @@ -1766,9 +1745,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => * * class Foo . companionModule --> object Foo */ - final def companionModule: Symbol = - if (isClass && !isRefinementClass) companionModule0 - else NoSymbol + def companionModule: Symbol = NoSymbol /** For a module: its linked class * For a plain class: its linked module or case factory. @@ -1776,18 +1753,14 @@ trait Symbols extends api.Symbols { self: SymbolTable => * * class Foo <-- companionSymbol --> object Foo */ - final def companionSymbol: Symbol = - if (isTerm) companionClass - else if (isClass) companionModule0 - else NoSymbol + def companionSymbol: Symbol = NoSymbol /** For a module class: its linked class * For a plain class: the module class of its linked module. * * class Foo <-- linkedClassOfClass --> class Foo$ */ - final def linkedClassOfClass: Symbol = - if (isModuleClass) companionClass else companionModule.moduleClass + def linkedClassOfClass: Symbol = NoSymbol /** * Returns the rawInfo of the owner. If the current phase has flat classes, @@ -1800,7 +1773,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => * symbol B in the decls of p. So to find a linked symbol ("object B" or "class B") * we need to apply flatten to B first. Fixes #2470. */ - private final def flatOwnerInfo: Type = { + protected final def flatOwnerInfo: Type = { if (needsFlatClasses) info owner.rawInfo @@ -1949,7 +1922,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Remove private modifier from symbol `sym`s definition. If `sym` is a * is not a constructor nor a static module rename it by expanding its name to avoid name clashes - * @param base the fully qualified name of this class will be appended if name expansion is needed + * @param base the fully qualified name of this class will be appended if name expansion is needed */ final def makeNotPrivate(base: Symbol) { if (this.isPrivate) { @@ -1979,23 +1952,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => case p :: _ => p case _ => NoSymbol } - - /** change name by appending $$<fully-qualified-name-of-class `base`> - * Do the same for any accessed symbols or setters/getters - */ - def expandName(base: Symbol) { - if (this.isTerm && this != NoSymbol && !hasFlag(EXPANDEDNAME)) { - setFlag(EXPANDEDNAME) - if (hasAccessorFlag && !isDeferred) { - accessed.expandName(base) - } else if (hasGetter) { - getter(owner).expandName(base) - setter(owner).expandName(base) - } - name = nme.expandedName(name.toTermName, base) - if (isType) name = name - } - } /* code for fixing nested objects def expandModuleClassName() { name = newTypeName(name.toString + "$") @@ -2020,7 +1976,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ def sealedDescendants: Set[Symbol] = children.flatMap(_.sealedDescendants) + this - def orElse[T](alt: => Symbol): Symbol = if (this ne NoSymbol) this else alt + @inline final def orElse[T](alt: => Symbol): Symbol = if (this ne NoSymbol) this else alt // ------ toString ------------------------------------------------------------------- @@ -2182,31 +2138,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => def infosString = infos.toString def debugLocationString = fullLocationString + " " + debugFlagString - def debugFlagString = hasFlagsToString(-1L) - def hasFlagsToString(mask: Long): String = flagsToString( - flags & mask, - if (hasAccessBoundary) privateWithin.toString else "" - ) - - /** String representation of symbol's variance */ - def varianceString: String = - if (variance == 1) "+" - else if (variance == -1) "-" - else "" - def defaultFlagMask = - if (isAbstractType) ExplicitFlags - else if (settings.debug.value) -1L - else if (owner.isRefinementClass) ExplicitFlags & ~OVERRIDE - else ExplicitFlags - - // make the error message more googlable - def flagsExplanationString = - if (isGADTSkolem) " (this is a GADT skolem)" - else "" - - def accessString = hasFlagsToString(PRIVATE | PROTECTED | LOCAL) - def defaultFlagString = hasFlagsToString(defaultFlagMask) private def defStringCompose(infoString: String) = compose( defaultFlagString, keyString, @@ -2238,12 +2170,24 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** A class for term symbols */ class TermSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName) extends Symbol(initOwner, initPos, initName) { - final override def isTerm = true + private[this] var _referenced: Symbol = NoSymbol + privateWithin = NoSymbol + final override def isTerm = true override def name: TermName = rawname.toTermName - privateWithin = NoSymbol + override def companionSymbol: Symbol = companionClass + override def moduleClass = if (isModule) referenced else NoSymbol - private[this] var _referenced: Symbol = NoSymbol + override def hasDefault = this hasFlag DEFAULTPARAM // overloaded with TRAIT + override def isBridge = this hasFlag BRIDGE + override def isEarlyInitialized = this hasFlag PRESUPER + override def isMethod = this hasFlag METHOD + override def isModule = this hasFlag MODULE + override def isOverloaded = this hasFlag OVERLOADED + override def isPackage = this hasFlag PACKAGE + override def isValueParameter = this hasFlag PARAM + + override def isPackageObject = isModule && (name == nme.PACKAGE) def referenced: Symbol = _referenced def referenced_=(x: Symbol) { _referenced = x } @@ -2277,11 +2221,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => if (name endsWith nme.OUTER) initialize.referenced else NoSymbol - override def moduleClass: Symbol = - if (hasFlag(MODULE)) referenced else NoSymbol - def setModuleClass(clazz: Symbol): TermSymbol = { - assert(hasFlag(MODULE), this) + assert(isModule, this) referenced = clazz this } @@ -2297,6 +2238,23 @@ trait Symbols extends api.Symbols { self: SymbolTable => referenced } + /** change name by appending $$<fully-qualified-name-of-class `base`> + * Do the same for any accessed symbols or setters/getters + */ + override def expandName(base: Symbol) { + if (!hasFlag(EXPANDEDNAME)) { + setFlag(EXPANDEDNAME) + if (hasAccessorFlag && !isDeferred) { + accessed.expandName(base) + } + else if (hasGetter) { + getter(owner).expandName(base) + setter(owner).expandName(base) + } + name = nme.expandedName(name.toTermName, base) + } + } + protected def doCookJavaRawInfo() { def cook(sym: Symbol) { require(sym.isJavaDefined, sym) @@ -2330,9 +2288,16 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** A class for module symbols */ class ModuleSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName) - extends TermSymbol(initOwner, initPos, initName) { + extends TermSymbol(initOwner, initPos, initName) with DistinguishingFlag { + def distinguishingFlag = MODULE + private var flatname: TermName = null + override def isModule = true + override def moduleClass = referenced + override def companionClass = + flatOwnerInfo.decl(name.toTypeName).suchThat(_ isCoDefinedWith this) + override def owner = ( if (!isMethod && needsFlatClasses) rawowner.owner else rawowner @@ -2346,21 +2311,38 @@ trait Symbols extends api.Symbols { self: SymbolTable => } else rawname.toTermName ) + } - override def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol = - owner.newModuleSymbol(name, pos, newFlags).copyAttrsFrom(this) + class PackageSymbol protected[Symbols] (owner0: Symbol, pos0: Position, name0: TermName) + extends ModuleSymbol(owner0, pos0, name0) with DistinguishingFlag { + override def distinguishingFlag = super.distinguishingFlag | PACKAGE + override def isPackage = true } /** A class for method symbols */ class MethodSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName) - extends TermSymbol(initOwner, initPos, initName) { - private var mtpePeriod = NoPeriod - private var mtpePre: Type = _ - private var mtpeResult: Type = _ - private var mtpeInfo: Type = _ - - override def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol = - owner.newMethodSymbol(name, pos, newFlags).copyAttrsFrom(this) + extends TermSymbol(initOwner, initPos, initName) with DistinguishingFlag { + def distinguishingFlag = METHOD + // MethodSymbols pick up MODULE when trait-owned object accessors are cloned + // during mixin composition. + override protected def neverHasFlags = super.neverHasFlags & ~MODULE + + private[this] var mtpePeriod = NoPeriod + private[this] var mtpePre: Type = _ + private[this] var mtpeResult: Type = _ + private[this] var mtpeInfo: Type = _ + + override def isMethod = true + override def isMacro = this hasFlag MACRO + override def isVarargsMethod = this hasFlag VARARGS + override def isLiftedMethod = this hasFlag LIFTED + // TODO - this seems a strange definition for "isSourceMethod", given that + // it does not make any specific effort to exclude synthetics. Figure out what + // this method is really for and what logic makes sense. + override def isSourceMethod = !(this hasFlag STABLE) // exclude all accessors + // unfortunately having the CASEACCESSOR flag does not actually mean you + // are a case accessor (you can also be a field.) + override def isCaseAccessorMethod = isCaseAccessor def typeAsMemberOf(pre: Type): Type = { if (mtpePeriod == currentPeriod) { @@ -2380,38 +2362,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => class AliasTypeSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName) extends TypeSymbol(initOwner, initPos, initName) { - // Temporary programmatic help tracking down who might do such a thing - override def setFlag(mask: Long): this.type = { - if (isSetting(DEFERRED, mask)) { - println("Setting DEFERRED on alias at") - (new Throwable).printStackTrace - } - super.setFlag(mask) - } final override def isAliasType = true - override def cloneSymbolImpl(owner: Symbol, newFlags: Long): AliasTypeSymbol = - owner.newAliasTypeSymbol(name, pos, newFlags) - } - - class AbstractTypeSymbol(initOwner: Symbol, initPos: Position, initName: TypeName) - extends TypeSymbol(initOwner, initPos, initName) with AbstractTypeMixin { - override def cloneSymbolImpl(owner: Symbol, newFlags: Long): AbstractTypeSymbol = - owner.newAbstractTypeSymbol(name, pos, newFlags) } - /** Might be mixed into TypeSymbol or TypeSkolem. - */ - trait AbstractTypeMixin extends TypeSymbol { - override def resetFlag(mask: Long): this.type = { - // Temporary programmatic help tracking down who might do such a thing - if (settings.debug.value) { - if (isClearing(DEFERRED, mask)) { - println("Clearing DEFERRED on abstract type at") - (new Throwable).printStackTrace - } - } - super.resetFlag(mask) - } + class AbstractTypeSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName) + extends TypeSymbol(initOwner, initPos, initName) { final override def isAbstractType = true override def existentialBound = this.info } @@ -2419,33 +2374,36 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** A class of type symbols. Alias and abstract types are direct instances * of this class. Classes are instances of a subclass. */ - abstract class TypeSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName) extends Symbol(initOwner, initPos, initName) { + abstract class TypeSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName) + extends Symbol(initOwner, initPos, initName) { privateWithin = NoSymbol + + final override def isType = true + override def isNonClassType = true + private var tyconCache: Type = null private var tyconRunId = NoRunId private var tpeCache: Type = _ private var tpePeriod = NoPeriod + override def isAbstractType = this hasFlag DEFERRED + override def isContravariant = this hasFlag CONTRAVARIANT + override def isCovariant = this hasFlag COVARIANT + override def isExistentialQuantified = isExistentiallyBound && !isSkolem + override def isExistentiallyBound = this hasFlag EXISTENTIAL + override def isTypeParameter = isTypeParameterOrSkolem && !isSkolem + override def isTypeParameterOrSkolem = this hasFlag PARAM + /** Overridden in subclasses for which it makes sense. */ def existentialBound: Type = abort("unexpected type: "+this.getClass+ " "+debugLocationString) + // a type symbol bound by an existential type, for instance the T in + // List[T] forSome { type T } + override def name: TypeName = super.name.toTypeName - final override def isType = true - override def isNonClassType = true - override def isAbstractType = { - if (settings.debug.value) { - if (isDeferred) { - println("TypeSymbol claims to be abstract type: " + this.getClass + " " + debugFlagString + " at ") - (new Throwable).printStackTrace - } - } - isDeferred - } - private def newTypeRef(targs: List[Type]) = { - val pre = if (hasFlag(PARAM | EXISTENTIAL)) NoPrefix else owner.thisType - typeRef(pre, this, targs) - } + private def newPrefix = if (this hasFlag EXISTENTIAL | PARAM) NoPrefix else owner.thisType + private def newTypeRef(targs: List[Type]) = typeRef(newPrefix, this, targs) /** Let's say you have a type definition * @@ -2538,8 +2496,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => } } + /** Default implementation. */ def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol = - owner.newTypeSymbol(name, pos, newFlags) + owner.newNonClassSymbol(name, pos, newFlags) incCounter(typeSymbolCount) } @@ -2559,12 +2518,19 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ class TypeSkolem protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName, origin: AnyRef) extends TypeSymbol(initOwner, initPos, initName) { - /** The skolemization level in place when the skolem was constructed */ val level = skolemizationLevel final override def isSkolem = true + override def isGADTSkolem = this hasFlag CASEACCESSOR | SYNTHETIC + override def isTypeSkolem = this hasFlag PARAM + override def isExistentialSkolem = this hasFlag EXISTENTIAL + override def isAbstractType = this hasFlag DEFERRED + + override def isExistentialQuantified = false + override def existentialBound = if (isAbstractType) this.info else super.existentialBound + /** If typeskolem comes from a type parameter, that parameter, otherwise skolem itself */ override def deSkolemize = origin match { case s: Symbol => s @@ -2588,17 +2554,92 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** A class for class symbols */ class ClassSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName) extends TypeSymbol(initOwner, initPos, initName) { - private[this] var flatname: TypeName = null - private[this] var source: AbstractFileType = null - private[this] var thissym: Symbol = this + private[this] var flatname: TypeName = _ + private[this] var source: AbstractFileType = _ + private[this] var thissym: Symbol = this + + private[this] var thisTypeCache: Type = _ + private[this] var thisTypePeriod = NoPeriod + private[this] var typeOfThisCache: Type = _ + private[this] var typeOfThisPeriod = NoPeriod + + override protected def alwaysHasFlags: Long = 0L + override protected def neverHasFlags: Long = 0L final override def isClass = true final override def isNonClassType = false final override def isAbstractType = false final override def isAliasType = false + override def isAbstractClass = this hasFlag ABSTRACT + override def isClassLocalToConstructor = this hasFlag INCONSTRUCTOR + override def isImplClass = this hasFlag IMPLCLASS + override def isModuleClass = this hasFlag MODULE + override def isPackageClass = this hasFlag PACKAGE + override def isTrait = this hasFlag TRAIT + + override def isConcreteClass = !(this hasFlag ABSTRACT | TRAIT) + override def isPackageObjectClass = isModuleClass && (name == tpnme.PACKAGE) + + def isTraitOrImplClass = this hasFlag TRAIT | IMPLCLASS + def isNonImplModuleClass = isModuleClass && !isImplClass + + override def isAnonymousClass = name containsName tpnme.ANON_CLASS_NAME + override def isAnonOrRefinementClass = isAnonymousClass || isRefinementClass + override def isNestedClass = !owner.isPackageClass + override def isNumericValueClass = definitions.isNumericValueClass(this) + override def isPrimitiveValueClass = definitions.isPrimitiveValueClass(this) + + /** Is this class locally defined? + * A class is local, if + * - it is anonymous, or + * - its owner is a value + * - it is defined within a local class + */ + override def isLocalClass = ( + isAnonOrRefinementClass + || isLocal + || !owner.isPackageClass && owner.isLocalClass + ) + override def isStableClass = (this hasFlag STABLE) || checkStable() + + private def checkStable() = { + def hasNoAbstractTypeMember(clazz: Symbol): Boolean = + (clazz hasFlag STABLE) || { + var e = clazz.info.decls.elems + while ((e ne null) && !(e.sym.isAbstractType && info.member(e.sym.name) == e.sym)) + e = e.next + e == null + } + (info.baseClasses forall hasNoAbstractTypeMember) && { + setFlag(STABLE) + true + } + } + + override def enclClassChain = this :: owner.enclClassChain + + /** A helper method that factors the common code used the discover a + * companion module of a class. If a companion module exists, its symbol is + * returned, otherwise, `NoSymbol` is returned. + */ + protected final def companionModule0: Symbol = + flatOwnerInfo.decl(name.toTermName).suchThat( + sym => sym.hasFlag(MODULE) && (sym isCoDefinedWith this) && !sym.isMethod) + + override def companionModule = companionModule0 + override def companionSymbol = companionModule0 + override def linkedClassOfClass = companionModule.moduleClass + override def existentialBound = GenPolyType(this.typeParams, TypeBounds.upper(this.classBound)) + def primaryConstructorName = if (isTraitOrImplClass) nme.MIXIN_CONSTRUCTOR else nme.CONSTRUCTOR + + override def primaryConstructor = { + val c = info decl primaryConstructorName + if (c.isOverloaded) c.alternatives.head else c + } + override def sourceFile = if (owner.isPackageClass) source else super.sourceFile @@ -2609,12 +2650,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => thissym = this } - private var thisTypeCache: Type = _ - private var thisTypePeriod = NoPeriod - - private var typeOfThisCache: Type = _ - private var typeOfThisPeriod = NoPeriod - /** the type this.type in this class */ override def thisType: Type = { val period = thisTypePeriod @@ -2625,8 +2660,24 @@ trait Symbols extends api.Symbols { self: SymbolTable => thisTypeCache } + /** the self type of an object foo is foo.type, not class<foo>.this.type + */ + override def typeOfThis: Type = { + if (isNonImplModuleClass && owner != NoSymbol) { + val period = typeOfThisPeriod + if (period != currentPeriod) { + typeOfThisPeriod = currentPeriod + if (!isValid(period)) + typeOfThisCache = singleType(owner.thisType, sourceModule) + } + typeOfThisCache + } + else thisSym.tpe + } + override def owner: Symbol = if (needsFlatClasses) rawowner.owner else rawowner + override def name: TypeName = ( if (needsFlatClasses) { if (flatname eq null) @@ -2640,27 +2691,12 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** A symbol carrying the self type of the class as its type */ override def thisSym: Symbol = thissym - /** the self type of an object foo is foo.type, not class<foo>.this.type - */ - override def typeOfThis: Type = { - if (getFlag(MODULE | IMPLCLASS) == MODULE.toLong && owner != NoSymbol) { - val period = typeOfThisPeriod - if (period != currentPeriod) { - typeOfThisPeriod = currentPeriod - if (!isValid(period)) - typeOfThisCache = singleType(owner.thisType, sourceModule) - } - typeOfThisCache - } - else thisSym.tpe - } - /** Sets the self type of the class */ override def typeOfThis_=(tp: Type) { thissym = newThisSym(pos).setInfo(tp) } - override def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol = { + override def cloneSymbolImpl(owner: Symbol, newFlags: Long): ClassSymbol = { val clone = owner.newClassSymbol(name, pos, newFlags) if (thisSym != this) { clone.typeOfThis = typeOfThis @@ -2669,12 +2705,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => clone } - override def sourceModule = - if (isModuleClass) companionModule else NoSymbol + // Must have this line. + override def sourceModule = if (isModuleClass) companionModule else NoSymbol override def firstParamAccessor = - info.decls.find(m => (m hasFlag PARAMACCESSOR) && m.isMethod) getOrElse NoSymbol - + info.decls.find(_ hasAllFlags PARAMACCESSOR | METHOD) getOrElse NoSymbol private[this] var childSet: Set[Symbol] = Set() override def children = childSet @@ -2688,12 +2723,17 @@ trait Symbols extends api.Symbols { self: SymbolTable => * plain class symbols! */ class ModuleClassSymbol protected[Symbols] (owner: Symbol, pos: Position, name: TypeName) - extends ClassSymbol(owner, pos, name) { + extends ClassSymbol(owner, pos, name) with DistinguishingFlag { + def distinguishingFlag = MODULE + private var module: Symbol = null - private var implicitMembersCacheValue: List[Symbol] = List() + private var implicitMembersCacheValue: List[Symbol] = Nil private var implicitMembersCacheKey1: Type = NoType private var implicitMembersCacheKey2: ScopeEntry = null + override def isModuleClass = true + override def linkedClassOfClass = companionClass + def implicitMembers: List[Symbol] = { val tp = info if ((implicitMembersCacheKey1 ne tp) || (implicitMembersCacheKey2 ne tp.decls.elems)) { @@ -2711,6 +2751,35 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def sourceModule_=(module: Symbol) { this.module = module } } + class PackageClassSymbol protected[Symbols] (owner0: Symbol, pos0: Position, name0: TypeName) + extends ModuleClassSymbol(owner0, pos0, name0) with DistinguishingFlag { + override def distinguishingFlag = super.distinguishingFlag | PACKAGE + override def sourceModule = companionModule + override def enclClassChain = Nil + override def isPackageClass = true + } + + class RefinementClassSymbol protected[Symbols] (owner0: Symbol, pos0: Position) + extends ClassSymbol(owner0, pos0, tpnme.REFINE_CLASS_NAME) { + override def name_=(name: Name) { + assert(false, "Cannot set name of RefinementClassSymbol to " + name) + super.name_=(name) + } + override def isRefinementClass = true + override def isAnonOrRefinementClass = true + override def isLocalClass = true + override def hasMeaninglessName = true + override def companionModule: Symbol = NoSymbol + + /** The mentioned twist. A refinement class has transowner X + * if any of its parents has transowner X. + */ + override def hasTransOwner(sym: Symbol) = ( + super.hasTransOwner(sym) + || info.parents.exists(_.typeSymbol hasTransOwner sym) + ) + } + class FreeVar(name0: TermName, val value: Any) extends TermSymbol(NoSymbol, NoPosition, name0) { override def hashCode = if (value == null) 0 else value.hashCode override def equals(other: Any): Boolean = other match { @@ -2730,12 +2799,20 @@ trait Symbols extends api.Symbols { self: SymbolTable => unlock() validTo = currentPeriod } + override def defaultFlagMask = AllFlags + override def exists = false + override def isHigherOrderTypeParameter = false + override def companionClass = NoSymbol + override def companionModule = NoSymbol + override def companionSymbol = NoSymbol override def isSubClass(that: Symbol) = false override def filter(cond: Symbol => Boolean) = this override def defString: String = toString override def locationString: String = "" + override def enclClassChain = Nil override def enclClass: Symbol = this override def enclosingTopLevelClass: Symbol = this + override def enclosingPackageClass: Symbol = this override def enclMethod: Symbol = this override def sourceFile: AbstractFileType = null override def ownerChain: List[Symbol] = List() @@ -2756,9 +2833,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => abort("no-symbol does not have a type constructor (this may indicate scalac cannot find fundamental classes)") } - protected def makeNoSymbol = new NoSymbol + protected def makeNoSymbol: NoSymbol = new NoSymbol - lazy val NoSymbol = makeNoSymbol + lazy val NoSymbol: NoSymbol = makeNoSymbol /** Derives a new list of symbols from the given list by mapping the given * list across the given function. Then fixes the info of all the new symbols @@ -2846,10 +2923,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** A class for type histories */ private sealed case class TypeHistory(var validFrom: Period, info: Type, prev: TypeHistory) { assert((prev eq null) || phaseId(validFrom) > phaseId(prev.validFrom), this) - assert(validFrom != NoPeriod) + assert(validFrom != NoPeriod, this) + override def toString() = "TypeHistory(" + phaseOf(validFrom)+":"+runId(validFrom) + "," + info + "," + prev + ")" - + def toList: List[TypeHistory] = this :: ( if (prev eq null) Nil else prev.toList ) } } diff --git a/src/compiler/scala/reflect/internal/TreePrinters.scala b/src/compiler/scala/reflect/internal/TreePrinters.scala index 8ed0ee6357..7a084304a8 100644 --- a/src/compiler/scala/reflect/internal/TreePrinters.scala +++ b/src/compiler/scala/reflect/internal/TreePrinters.scala @@ -175,7 +175,7 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable => printAnnotations(tree) printModifiers(tree, mods) val word = - if (mods.hasTraitFlag) "trait" + if (mods.isTrait) "trait" else if (ifSym(tree, _.isModuleClass)) "object" else "class" diff --git a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala index f1ec64bda9..f89aa9bf5c 100644 --- a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala +++ b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala @@ -257,12 +257,11 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ { } def isModuleFlag = (flags & MODULE) != 0L - def isMethodFlag = (flags & METHOD) != 0L def isClassRoot = (name == classRoot.name) && (owner == classRoot.owner) def isModuleRoot = (name == moduleRoot.name) && (owner == moduleRoot.owner) + def pflags = flags & PickledFlags def finishSym(sym: Symbol): Symbol = { - sym.flags = flags & PickledFlags sym.privateWithin = privateWithin sym.info = ( if (atEnd) { @@ -282,27 +281,27 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ { } finishSym(tag match { - case TYPEsym => owner.newAbstractType(name.toTypeName) - case ALIASsym => owner.newAliasType(name.toTypeName) + case TYPEsym | ALIASsym => + owner.newNonClassSymbol(name.toTypeName, NoPosition, pflags) case CLASSsym => - val sym = (isClassRoot, isModuleFlag) match { - case (true, true) => moduleRoot.moduleClass - case (true, false) => classRoot - case (false, true) => owner.newModuleClass(name.toTypeName) - case (false, false) => owner.newClass(name.toTypeName) - } + val sym = ( + if (isClassRoot) { + if (isModuleFlag) moduleRoot.moduleClass setFlag pflags + else classRoot setFlag pflags + } + else owner.newClassSymbol(name.toTypeName, NoPosition, pflags) + ) if (!atEnd) sym.typeOfThis = newLazyTypeRef(readNat()) sym case MODULEsym => val clazz = at(inforef, () => readType()).typeSymbol // after the NMT_TRANSITION period, we can leave off the () => ... () - if (isModuleRoot) moduleRoot - else owner.newLinkedModule(clazz) + if (isModuleRoot) moduleRoot setFlag pflags + else owner.newLinkedModule(clazz, pflags) case VALsym => if (isModuleRoot) { assert(false); NoSymbol } - else if (isMethodFlag) owner.newMethod(name.toTermName) - else owner.newValue(name.toTermName) + else owner.newTermSymbol(name.toTermName, NoPosition, pflags) case _ => errorBadSignature("bad symbol tag: " + tag) diff --git a/src/compiler/scala/reflect/internal/util/Collections.scala b/src/compiler/scala/reflect/internal/util/Collections.scala index d26a1abadb..9dbf1adeef 100644 --- a/src/compiler/scala/reflect/internal/util/Collections.scala +++ b/src/compiler/scala/reflect/internal/util/Collections.scala @@ -10,6 +10,8 @@ import scala.annotation.tailrec import mutable.ListBuffer /** Profiler driven changes. + * TODO - inlining doesn't work from here because of the bug that + * methods in traits aren't inlined. */ trait Collections { /** True if all three arguments have the same number of elements and @@ -75,7 +77,8 @@ trait Collections { } } - @inline final def findOrElse[A](xs: TraversableOnce[A])(p: A => Boolean)(orElse: => A): A = { + // @inline + final def findOrElse[A](xs: TraversableOnce[A])(p: A => Boolean)(orElse: => A): A = { xs find p getOrElse orElse } diff --git a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala index 3f2fa30be2..85f7b56920 100644 --- a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala +++ b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala @@ -17,7 +17,7 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable => override def newFreeVar(name: TermName, tpe: Type, value: Any, newFlags: Long = 0L): FreeVar = new FreeVar(name, value) with SynchronizedTermSymbol initFlags newFlags setInfo tpe - override protected def makeNoSymbol = new NoSymbol with SynchronizedSymbol + override protected def makeNoSymbol: NoSymbol = new NoSymbol with SynchronizedSymbol trait SynchronizedSymbol extends Symbol { @@ -55,32 +55,45 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable => // ------ creators ------------------------------------------------------------------- - override def newTermSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): TermSymbol = - new TermSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags + override protected def createTypeSymbol(name: TypeName, pos: Position, newFlags: Long): TypeSymbol = + new TypeSymbol(this, pos, name) with SynchronizedTypeSymbol initFlags newFlags - override def newAbstractTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): AbstractTypeSymbol = + override protected def createAbstractTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AbstractTypeSymbol = new AbstractTypeSymbol(this, pos, name) with SynchronizedTypeSymbol initFlags newFlags - override def newAliasTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): AliasTypeSymbol = + override protected def createAliasTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AliasTypeSymbol = new AliasTypeSymbol(this, pos, name) with SynchronizedTypeSymbol initFlags newFlags - override def newModuleSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol = - new ModuleSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags - - override def newMethodSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): MethodSymbol = - new MethodSymbol(this, pos, name) with SynchronizedMethodSymbol initFlags newFlags + override protected def createTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position, newFlags: Long): TypeSkolem = + new TypeSkolem(this, pos, name, origin) with SynchronizedTypeSymbol initFlags newFlags - override def newClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol = + override protected def createClassSymbol(name: TypeName, pos: Position, newFlags: Long): ClassSymbol = new ClassSymbol(this, pos, name) with SynchronizedClassSymbol initFlags newFlags - override def newModuleClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleClassSymbol = + override protected def createModuleClassSymbol(name: TypeName, pos: Position, newFlags: Long): ModuleClassSymbol = new ModuleClassSymbol(this, pos, name) with SynchronizedModuleClassSymbol initFlags newFlags - override def newTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position = NoPosition, newFlags: Long = 0L): TypeSkolem = - if ((newFlags & DEFERRED) == 0L) - new TypeSkolem(this, pos, name, origin) with SynchronizedTypeSymbol initFlags newFlags - else - new TypeSkolem(this, pos, name, origin) with AbstractTypeMixin with SynchronizedTypeSymbol initFlags newFlags + override protected def createPackageClassSymbol(name: TypeName, pos: Position, newFlags: Long): PackageClassSymbol = + new PackageClassSymbol(this, pos, name) with SynchronizedModuleClassSymbol initFlags newFlags + + override protected def createRefinementClassSymbol(pos: Position, newFlags: Long): RefinementClassSymbol = + new RefinementClassSymbol(this, pos) with SynchronizedClassSymbol initFlags newFlags + + override protected def createTermSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol = + new TermSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags + + override protected def createMethodSymbol(name: TermName, pos: Position, newFlags: Long): MethodSymbol = + new MethodSymbol(this, pos, name) with SynchronizedMethodSymbol initFlags newFlags + + override protected def createModuleSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol = + new ModuleSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags + + override protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): PackageSymbol = + new PackageSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags + + // TODO + // override protected def createValueParameterSymbol(name: TermName, pos: Position, newFlags: Long) + // override protected def createValueMemberSymbol(name: TermName, pos: Position, newFlags: Long) } // ------- subclasses --------------------------------------------------------------------- diff --git a/src/compiler/scala/reflect/runtime/Universe.scala b/src/compiler/scala/reflect/runtime/Universe.scala index 7a5dda3d8e..dca6d6041b 100644 --- a/src/compiler/scala/reflect/runtime/Universe.scala +++ b/src/compiler/scala/reflect/runtime/Universe.scala @@ -40,7 +40,7 @@ class Universe extends SymbolTable { definitions.AnyValClass // force it. type TreeAnnotation = Position - val NoTreeAnnotation: TreeAnnotation = NoPosition + def NoTreeAnnotation: TreeAnnotation = NoPosition def positionToAnnotation(pos: Position): TreeAnnotation = pos // TODO def annotationToPosition(annot: TreeAnnotation): Position = annot //TODO diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 6a30dc2a0f..5e0c24d304 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -220,10 +220,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb (settings.log.isSetByUser) && ((settings.log containsPhase globalPhase) || (settings.log containsPhase phase)) ) - def atPhaseStackMessage = atPhaseStack match { - case Nil => "" - case ps => ps.reverseMap("->" + _).mkString("(", " ", ")") - } // Over 200 closure objects are eliminated by inlining this. @inline final def log(msg: => AnyRef) { if (shouldLogAtThisPhase) @@ -1006,7 +1002,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb /** Set phase to a newly created syntaxAnalyzer and call definitions.init. */ val parserPhase: Phase = syntaxAnalyzer.newPhase(NoPhase) phase = parserPhase - definitions.init + definitions.init() // Flush the cache in the terminal phase: the chain could have been built // before without being used. (This happens in the interpreter.) diff --git a/src/compiler/scala/tools/nsc/ast/Reifiers.scala b/src/compiler/scala/tools/nsc/ast/Reifiers.scala index 7ece8bbd31..04468a096d 100644 --- a/src/compiler/scala/tools/nsc/ast/Reifiers.scala +++ b/src/compiler/scala/tools/nsc/ast/Reifiers.scala @@ -199,7 +199,7 @@ trait Reifiers { self: Global => ValDef(NoMods, localName(sym), TypeTree(), Apply( Select(reify(sym.owner), "newNestedSymbol"), - List(reify(sym.name), reify(sym.pos), Literal(Constant(sym.flags))) + List(reify(sym.name), reify(sym.pos), Literal(Constant(sym.flags)), Literal(Constant(sym.isClass))) ) ) } diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala index 9f361e5bcc..569cb4977b 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala @@ -44,7 +44,7 @@ abstract class TreeInfo extends reflect.internal.TreeInfo { } def isInterface(mods: HasFlags, body: List[Tree]) = - mods.hasTraitFlag && (body forall isInterfaceMember) + mods.isTrait && (body forall isInterfaceMember) def isAllowedInUniversalTrait(stat: Tree): Boolean = stat match { case _: ValDef => false diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 45325b4694..fa2fc54ac0 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -2600,7 +2600,6 @@ self => in.nextToken val nameOffset = in.offset val name = identForType() - def isTrait = mods.hasTraitFlag atPos(start, if (name == tpnme.ERROR) start else nameOffset) { savingClassContextBounds { @@ -2608,16 +2607,16 @@ self => val tparams = typeParamClauseOpt(name, contextBoundBuf) classContextBounds = contextBoundBuf.toList val tstart = in.offset :: classContextBounds.map(_.pos.startOrPoint) min; - if (!classContextBounds.isEmpty && isTrait) { + if (!classContextBounds.isEmpty && mods.isTrait) { syntaxError("traits cannot have type parameters with context bounds `: ...' nor view bounds `<% ...'", false) classContextBounds = List() } val constrAnnots = constructorAnnotations() val (constrMods, vparamss) = - if (isTrait) (Modifiers(Flags.TRAIT), List()) + if (mods.isTrait) (Modifiers(Flags.TRAIT), List()) else (accessModifierOpt(), paramClauses(name, classContextBounds, mods.isCase)) var mods1 = mods - if (isTrait) { + if (mods.isTrait) { if (settings.YvirtClasses && in.token == SUBTYPE) mods1 |= Flags.DEFERRED } else if (in.token == SUBTYPE) { syntaxError("classes are not allowed to be virtual", false) @@ -2709,7 +2708,7 @@ self => } def isInterface(mods: Modifiers, body: List[Tree]): Boolean = - mods.hasTraitFlag && (body forall treeInfo.isInterfaceMember) + mods.isTrait && (body forall treeInfo.isInterfaceMember) /** {{{ * ClassTemplateOpt ::= `extends' ClassTemplate | [[`extends'] TemplateBody] @@ -2719,9 +2718,9 @@ self => */ def templateOpt(mods: Modifiers, name: Name, constrMods: Modifiers, vparamss: List[List[ValDef]], tstart: Int): Template = { val (parents0, argss, self, body) = ( - if (in.token == EXTENDS || in.token == SUBTYPE && mods.hasTraitFlag) { + if (in.token == EXTENDS || in.token == SUBTYPE && mods.isTrait) { in.nextToken() - template(mods.hasTraitFlag) + template(mods.isTrait) } else { newLineOptWhenFollowedBy(LBRACE) diff --git a/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala b/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala index 27df45b563..314a3b45a0 100644 --- a/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala +++ b/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala @@ -38,10 +38,10 @@ trait JavaPlatform extends Platform { genJVM // generate .class files ) ++ depAnalysisPhase - lazy val externalEquals = getMember(BoxesRunTimeClass, nme.equals_) - lazy val externalEqualsNumNum = getMember(BoxesRunTimeClass, nme.equalsNumNum) - lazy val externalEqualsNumChar = getMember(BoxesRunTimeClass, nme.equalsNumChar) - lazy val externalEqualsNumObject = getMember(BoxesRunTimeClass, nme.equalsNumObject) + lazy val externalEquals = getDecl(BoxesRunTimeClass, nme.equals_) + lazy val externalEqualsNumNum = getDecl(BoxesRunTimeClass, nme.equalsNumNum) + lazy val externalEqualsNumChar = getDecl(BoxesRunTimeClass, nme.equalsNumChar) + lazy val externalEqualsNumObject = getDecl(BoxesRunTimeClass, nme.equalsNumObject) /** We could get away with excluding BoxedBooleanClass for the * purpose of equality testing since it need not compare equal diff --git a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala index 2ff0c1926c..7ad7cadd92 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala @@ -142,7 +142,7 @@ trait TypeKinds { self: ICodes => def lub0(tk1: TypeKind, tk2: TypeKind): Type = beforeUncurry { import definitions._ val tp = global.lub(List(tk1.toType, tk2.toType)) - val (front, rest) = tp.parents span (_.typeSymbol.hasTraitFlag) + val (front, rest) = tp.parents span (_.typeSymbol.isTrait) if (front.isEmpty || rest.isEmpty || rest.head.typeSymbol == ObjectClass) tp else rest.head diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index 7b7135d180..18dc4aa56c 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -1281,7 +1281,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with val jname = javaName(method) val jtype = javaType(method).asInstanceOf[JMethodType] - def debugMsg(invoke: String) { + def dbg(invoke: String) { debuglog("%s %s %s.%s:%s".format(invoke, receiver.accessString, jowner, jname, jtype)) } @@ -1299,14 +1299,14 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with } style match { - case Static(true) => jcode.emitINVOKESPECIAL (jowner, jname, jtype) ; debugMsg("invokespecial") - case Static(false) => jcode.emitINVOKESTATIC (jowner, jname, jtype) ; debugMsg("invokestatic") - case Dynamic if isInterfaceCall(receiver) => jcode.emitINVOKEINTERFACE(jowner, jname, jtype) ; debugMsg("invokinterface") - case Dynamic => jcode.emitINVOKEVIRTUAL (jowner, jname, jtype) ; debugMsg("invokevirtual") + case Static(true) => dbg("invokespecial"); jcode.emitINVOKESPECIAL(jowner, jname, jtype) + case Static(false) => dbg("invokestatic"); jcode.emitINVOKESTATIC(jowner, jname, jtype) + case Dynamic if isInterfaceCall(receiver) => dbg("invokinterface"); jcode.emitINVOKEINTERFACE(jowner, jname, jtype) + case Dynamic => dbg("invokevirtual"); jcode.emitINVOKEVIRTUAL(jowner, jname, jtype) case SuperCall(_) => + dbg("invokespecial") jcode.emitINVOKESPECIAL(jowner, jname, jtype) initModule() - debugMsg("invokespecial") } } diff --git a/src/compiler/scala/tools/nsc/symtab/Positions.scala b/src/compiler/scala/tools/nsc/symtab/Positions.scala index 680b06f8ce..94b619de90 100644 --- a/src/compiler/scala/tools/nsc/symtab/Positions.scala +++ b/src/compiler/scala/tools/nsc/symtab/Positions.scala @@ -15,7 +15,7 @@ self: scala.tools.nsc.symtab.SymbolTable => val NoPosition = scala.tools.nsc.util.NoPosition type TreeAnnotation = scala.tools.nsc.util.TreeAnnotation - val NoTreeAnnotation: TreeAnnotation = NoPosition + def NoTreeAnnotation: TreeAnnotation = NoPosition def positionToAnnotation(pos: Position): TreeAnnotation = pos def annotationToPosition(annot: TreeAnnotation): Position = annot.pos override def _checkSetAnnotation(tree: Tree, annot: TreeAnnotation): Unit = { diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala index 68af518d3a..775a7a9d38 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala @@ -625,11 +625,11 @@ abstract class ICodeReader extends ClassfileParser { * such as Int.box(5). */ def isBox(m: Symbol): Boolean = - (m.owner == definitions.BoxesRunTimeClass.moduleClass + (m.owner == definitions.BoxesRunTimeClass && m.name.startsWith("boxTo")) def isUnbox(m: Symbol): Boolean = - (m.owner == definitions.BoxesRunTimeClass.moduleClass + (m.owner == definitions.BoxesRunTimeClass && m.name.startsWith("unboxTo")) /** Return the icode class that should include members with the given flags. diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala index 39e2cbe694..dde166d64b 100644 --- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala +++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala @@ -43,11 +43,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure => */ private def isInterfaceMember(sym: Symbol) = ( sym.isType || { - // !!! Shouldn't the following code be equivalent to leaving - // out the "sym.info" call and starting with "sym.initialize.isMethod" ? - // Because, it is not, which I found a little disturbing. The compiler - // fails to bootstrap with an error somewhere. - sym.info // initialize to set lateMETHOD flag if necessary + sym.info // initialize to set lateMETHOD flag if necessary ( sym.isMethod && !sym.isLabel @@ -71,6 +67,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure => /** Return the implementation class of a trait; create a new one of one does not yet exist */ def implClass(iface: Symbol): Symbol = { iface.info + def implClassFlags = iface.flags & ~(INTERFACE | lateINTERFACE) | IMPLCLASS implClassMap.getOrElse(iface, { atPhase(implClassPhase) { @@ -101,7 +98,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure => else log("not unlinking existing " + impl + " as the impl class is not visible on the classpath.") } if (impl == NoSymbol) { - impl = iface.cloneSymbolImpl(iface.owner) + impl = iface.cloneSymbolImpl(iface.owner, implClassFlags) impl.name = implName impl.sourceFile = iface.sourceFile if (iface.owner.isClass) @@ -109,7 +106,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure => } if (currentRun.compiles(iface)) currentRun.symSource(impl) = iface.sourceFile impl setPos iface.pos - impl.flags = iface.flags & ~(INTERFACE | lateINTERFACE) | IMPLCLASS + impl.flags = implClassFlags impl setInfo new LazyImplClassType(iface) implClassMap(iface) = impl debuglog( diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index b21fa4bc83..e6f5dc5b5f 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -299,11 +299,11 @@ abstract class CleanUp extends Transform with ast.TreeDSL { def testForName(name: Name): Tree => Tree = t => ( if (nme.CommonOpNames(name)) - gen.mkMethodCall(getMember(BoxesRunTimeClass, nme.isBoxedNumberOrBoolean), t :: Nil) + gen.mkMethodCall(definitions.Boxes_isNumberOrBool, t :: Nil) else if (nme.BooleanOpNames(name)) t IS_OBJ BoxedBooleanClass.tpe else - gen.mkMethodCall(getMember(BoxesRunTimeClass, nme.isBoxedNumber), t :: Nil) + gen.mkMethodCall(definitions.Boxes_isNumber, t :: Nil) ) /** The Tree => Tree function in the return is necessary to prevent the original qual @@ -318,8 +318,10 @@ abstract class CleanUp extends Transform with ast.TreeDSL { else if (params.tail.isEmpty) nme.primitiveInfixMethodName(name) else nme.NO_NAME ) - if (methodName == nme.NO_NAME) None - else Some((getMember(BoxesRunTimeClass, methodName), testForName(name))) + definitions.getDeclIfDefined(BoxesRunTimeClass, methodName) match { + case NoSymbol => None + case sym => assert(!sym.isOverloaded, sym) ; Some((sym, testForName(name))) + } } /* ### BOXING PARAMS & UNBOXING RESULTS ### */ diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index 595c1486b6..16c7c3c3ff 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -93,7 +93,7 @@ abstract class ExplicitOuter extends InfoTransform } def newOuterAccessor(clazz: Symbol) = { val accFlags = SYNTHETIC | METHOD | STABLE | ( if (clazz.isTrait) DEFERRED else 0 ) - val sym = clazz.newMethodSymbol(nme.OUTER, clazz.pos, accFlags) + val sym = clazz.newMethod(nme.OUTER, clazz.pos, accFlags) val restpe = if (clazz.isTrait) clazz.outerClass.tpe else clazz.outerClass.thisType sym expandName clazz diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala index 5104518dd9..3515c1d521 100644 --- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala +++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala @@ -68,7 +68,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { private def normalize(stpe: Type, clazz: Symbol): Type = stpe match { case PolyType(tparams, restpe) => - GenPolyType(tparams dropRight clazz.typeParams.length, normalize(restpe, clazz)) + GenPolyType(tparams dropRight clazz.typeParams.length, normalize(restpe.substSym(tparams takeRight clazz.typeParams.length, clazz.typeParams), clazz)) case MethodType(tparams, restpe) => restpe case _ => diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala index 8856024a30..ac76862094 100644 --- a/src/compiler/scala/tools/nsc/transform/Flatten.scala +++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala @@ -108,7 +108,7 @@ abstract class Flatten extends InfoTransform { tree match { case PackageDef(_, _) => liftedDefs(tree.symbol.moduleClass) = new ListBuffer - case Template(_, _, _) if tree.symbol.owner.hasPackageFlag => + case Template(_, _, _) if tree.symbol.isDefinedInPackage => liftedDefs(tree.symbol.owner) = new ListBuffer case _ => } diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index adbb7d43d0..ed410a76db 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -136,7 +136,6 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { sym = member.matchingSymbol(bcs.head, base.thisType).suchThat(sym => !sym.hasFlag(DEFERRED | BRIDGE)) bcs = bcs.tail } - assert(sym != NoSymbol, member) sym } @@ -339,8 +338,14 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { else if (mixinMember.isSuperAccessor) { // mixin super accessors val superAccessor = addMember(clazz, mixinMember.cloneSymbol(clazz)) setPos clazz.pos assert(superAccessor.alias != NoSymbol, superAccessor) - val alias1 = rebindSuper(clazz, mixinMember.alias, mixinClass) - superAccessor.asInstanceOf[TermSymbol] setAlias alias1 + + rebindSuper(clazz, mixinMember.alias, mixinClass) match { + case NoSymbol => + unit.error(clazz.pos, "Member %s of mixin %s is missing a concrete super implementation.".format( + mixinMember.alias, mixinClass)) + case alias1 => + superAccessor.asInstanceOf[TermSymbol] setAlias alias1 + } } else if (mixinMember.isMethod && mixinMember.isModule && mixinMember.hasNoFlags(LIFTED | BRIDGE)) { // mixin objects: todo what happens with abstract objects? diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index 49ddb985dc..ff0bdf7580 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -661,7 +661,7 @@ trait ContextErrors { } private def ambiguousErrorMsgPos(pos: Position, pre: Type, sym1: Symbol, sym2: Symbol, rest: String) = - if (sym1.hasDefaultFlag && sym2.hasDefaultFlag && sym1.enclClass == sym2.enclClass) { + if (sym1.hasDefault && sym2.hasDefault && sym1.enclClass == sym2.enclClass) { val methodName = nme.defaultGetterToMethod(sym1.name) (sym1.enclClass.pos, "in "+ sym1.enclClass +", multiple overloaded alternatives of " + methodName + diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index dba31f7bca..ebf8e3fc9a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -699,7 +699,7 @@ trait Infer { case NamedType(name, _) => Some(name) case _ => None })._1 - if (missing forall (_.hasDefaultFlag)) { + if (missing forall (_.hasDefault)) { // add defaults as named arguments val argtpes1 = argtpes0 ::: (missing map (p => NamedType(p.name, p.tpe))) isApplicable(undetparams, ftpe, argtpes1, pt) diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 1b505d1e5d..7ea78a81d5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -529,7 +529,7 @@ trait Namers extends MethodSynthesis { def enterCopyMethodOrGetter(tree: Tree, tparams: List[TypeDef]): Symbol = { val sym = tree.symbol val lazyType = completerOf(tree, tparams) - def completeCopyFirst = sym.isSynthetic && (!sym.hasDefaultFlag || sym.owner.info.member(nme.copy).isSynthetic) + def completeCopyFirst = sym.isSynthetic && (!sym.hasDefault || sym.owner.info.member(nme.copy).isSynthetic) def completeCopyMethod(clazz: Symbol) { // the 'copy' method of case classes needs a special type completer to make // bug0054.scala (and others) work. the copy method has to take exactly the same @@ -1045,7 +1045,7 @@ trait Namers extends MethodSynthesis { } ) // #2382: return type of default getters are always @uncheckedVariance - if (meth.hasDefaultFlag) + if (meth.hasDefault) rt.withAnnotation(AnnotationInfo(uncheckedVarianceClass.tpe, List(), List())) else rt }) @@ -1095,8 +1095,8 @@ trait Namers extends MethodSynthesis { for (vparam <- vparams) { val sym = vparam.symbol // true if the corresponding parameter of the base class has a default argument - val baseHasDefault = overrides && baseParams.head.hasDefaultFlag - if (sym.hasDefaultFlag) { + val baseHasDefault = overrides && baseParams.head.hasDefault + if (sym.hasDefault) { // generate a default getter for that argument val oflag = if (baseHasDefault) OVERRIDE else 0 val name = nme.defaultGetterName(meth.name, posCounter) diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index c621497618..2573678f8c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -377,7 +377,7 @@ trait NamesDefaults { self: Analyzer => pos: util.Position, context: Context): (List[Tree], List[Symbol]) = { if (givenArgs.length < params.length) { val (missing, positional) = missingParams(givenArgs, params) - if (missing forall (_.hasDefaultFlag)) { + if (missing forall (_.hasDefault)) { val defaultArgs = missing flatMap (p => { val defGetter = defaultGetter(p, context) // TODO #3649 can create spurious errors when companion object is gone (because it becomes unlinked from scope) @@ -399,7 +399,7 @@ trait NamesDefaults { self: Analyzer => } }) (givenArgs ::: defaultArgs, Nil) - } else (givenArgs, missing filterNot (_.hasDefaultFlag)) + } else (givenArgs, missing filterNot (_.hasDefault)) } else (givenArgs, Nil) } diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 54b711cebc..68a722aab4 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -123,7 +123,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R defaultMethodNames.distinct foreach { name => val methods = clazz.info.findMember(name, 0L, METHOD, false).alternatives - val haveDefaults = methods filter (sym => sym.hasParamWhich(_.hasDefaultFlag) && !nme.isProtectedAccessorName(sym.name)) + val haveDefaults = methods filter (sym => sym.hasParamWhich(_.hasDefault) && !nme.isProtectedAccessorName(sym.name)) if (haveDefaults.lengthCompare(1) > 0) { val owners = haveDefaults map (_.owner) @@ -381,7 +381,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R overrideError("cannot be used here - class definitions cannot be overridden"); } else if (!other.isDeferred && member.isClass) { overrideError("cannot be used here - classes can only override abstract types"); - } else if (other.isFinal) { // (1.2) + } else if (other.isEffectivelyFinal) { // (1.2) overrideError("cannot override final member"); // synthetic exclusion needed for (at least) default getters. } else if (!other.isDeferred && !member.isAnyOverride && !member.isSynthetic) { @@ -662,7 +662,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R } // Check the remainder for invalid absoverride. - for (member <- rest ; if ((member hasFlag ABSOVERRIDE) && member.isIncompleteIn(clazz))) { + for (member <- rest ; if (member.isAbstractOverride && member.isIncompleteIn(clazz))) { val other = member.superSymbol(clazz) val explanation = if (other != NoSymbol) " and overrides incomplete superclass member " + infoString(other) @@ -756,11 +756,10 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R // 4. Check that every defined member with an `override` modifier overrides some other member. for (member <- clazz.info.decls) - if ((member hasFlag (OVERRIDE | ABSOVERRIDE)) && - !(clazz.thisType.baseClasses exists (hasMatchingSym(_, member)))) { + if (member.isAnyOverride && !(clazz.thisType.baseClasses exists (hasMatchingSym(_, member)))) { // for (bc <- clazz.info.baseClasses.tail) Console.println("" + bc + " has " + bc.info.decl(member.name) + ":" + bc.info.decl(member.name).tpe);//DEBUG unit.error(member.pos, member.toString() + " overrides nothing"); - member resetFlag OVERRIDE + member resetFlag (OVERRIDE | ABSOVERRIDE) // Any Override } } diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index 94733369a8..43cbea83ff 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -121,7 +121,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT if (sym.isDeferred) { val member = sym.overridingSymbol(clazz); if (mix != tpnme.EMPTY || member == NoSymbol || - !((member hasFlag ABSOVERRIDE) && member.isIncompleteIn(clazz))) + !(member.isAbstractOverride && member.isIncompleteIn(clazz))) unit.error(sel.pos, ""+sym.fullLocationString+" is accessed from super. It may not be abstract "+ "unless it is overridden by a member declared `abstract' and `override'"); } diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala index 105c2c0b98..8895905ca7 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala @@ -14,6 +14,20 @@ import util.returning abstract class TreeCheckers extends Analyzer { import global._ + private val everything = ListBuffer[(Phase, Map[Tree, (Symbol, Type)])]() + private val currentTrees = mutable.Map[Tree, (Symbol, Type)]() + + if (settings.debug.value) { + sys addShutdownHook { + for ((ph, map) <- everything.toList) { + println("\n>>>> " + ph + "\n") + for ((tree, (sym, tpe)) <- map.toList.sortBy(_._1.summaryString)) { + println("%20s %20s %s".format(sym, tpe, ("" + tree) take 50)) + } + } + } + } + private def classstr(x: AnyRef) = x.getClass.getName split """\\.|\\$""" last; private def typestr(x: Type) = " (tpe = " + x + ")" private def treestr(t: Tree) = t + " [" + classstr(t) + "]" + typestr(t.tpe) @@ -92,11 +106,16 @@ abstract class TreeCheckers extends Analyzer { if (maps.isEmpty || maps.last._1 != ph) maps += ((ph, new PhaseMap)) + currentTrees.clear() traverse(unit.body) + everything += ((ph, currentTrees.toMap)) + reportChanges() } override def traverse(tree: Tree): Unit = { val sym = tree.symbol + currentTrees(tree) = ((sym, tree.tpe)) + if (sym != null && sym != NoSymbol) { record(sym, tree) tree match { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 36c81b09cd..76e1d40af9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1922,7 +1922,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { rhs1 = checkDead(rhs1) if (!isPastTyper && meth.owner.isClass && - meth.paramss.exists(ps => ps.exists(_.hasDefaultFlag) && isRepeatedParamType(ps.last.tpe))) + meth.paramss.exists(ps => ps.exists(_.hasDefault) && isRepeatedParamType(ps.last.tpe))) StarWithDefaultError(meth) if (!isPastTyper) { @@ -2492,7 +2492,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { (e.sym.isType || inBlock || (e.sym.tpe matches e1.sym.tpe) || e.sym.isMacro && e1.sym.isMacro)) // default getters are defined twice when multiple overloads have defaults. an // error for this is issued in RefChecks.checkDefaultsInOverloaded - if (!e.sym.isErroneous && !e1.sym.isErroneous && !e.sym.hasDefaultFlag && + if (!e.sym.isErroneous && !e1.sym.isErroneous && !e.sym.hasDefault && !e.sym.hasAnnotation(BridgeClass) && !e1.sym.hasAnnotation(BridgeClass)) { log("Double definition detected:\n " + ((e.sym.getClass, e.sym.info, e.sym.ownerChain)) + "\n " + @@ -3106,7 +3106,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { for (sym <- names) { // make sure the flags are up to date before erroring (jvm/t3415 fails otherwise) sym.initialize - if (!sym.hasAnnotation(AnnotationDefaultAttr) && !sym.hasDefaultFlag) + if (!sym.hasAnnotation(AnnotationDefaultAttr) && !sym.hasDefault) reportAnnotationError(AnnotationMissingArgError(ann, annType, sym)) } diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala index 1b01355108..be9e0c290a 100644 --- a/src/library/scala/StringContext.scala +++ b/src/library/scala/StringContext.scala @@ -79,15 +79,13 @@ case class StringContext(parts: String*) { * start a format specifier), then the string format specifier `%s` is inserted. * * 2. Any `%` characters not in formatting positions are left in the resulting - * string literally. This is achieved by replacing each such occurrence by a string - * format specifier `%s` and adding a corresponding argument string `"%"`. + * string literally. This is achieved by replacing each such occurrence by the + * format specifier `%%`. */ def f(args: Any*) = { checkLengths(args: _*) val pi = parts.iterator - val ai = args.iterator val bldr = new java.lang.StringBuilder - val args1 = new ArrayBuffer[Any] def copyString(first: Boolean): Unit = { val str = treatEscapes(pi.next()) val strIsEmpty = str.length == 0 @@ -98,23 +96,23 @@ case class StringContext(parts: String*) { bldr append "%s" idx = 1 } - val len = str.length - while (idx < len) { - if (str(idx) == '%') { - bldr append (str substring (start, idx)) append "%s" - args1 += "%" - start = idx + 1 + if (!strIsEmpty) { + val len = str.length + while (idx < len) { + if (str(idx) == '%') { + bldr append (str substring (start, idx)) append "%%" + start = idx + 1 + } + idx += 1 } - idx += 1 + bldr append (str substring (start, idx)) } - if (!strIsEmpty) bldr append (str substring (start, idx)) } copyString(first = true) while (pi.hasNext) { - args1 += ai.next() copyString(first = false) } - bldr.toString format (args1: _*) + bldr.toString format (args: _*) } } @@ -144,7 +142,7 @@ object StringContext { var cur = 0 var idx = 0 def output(ch: Char) = { - bldr append str substring (start, cur) + bldr append str.substring (start, cur) bldr append ch start = idx } diff --git a/src/library/scala/annotation/ClassfileAnnotation.scala b/src/library/scala/annotation/ClassfileAnnotation.scala index 582e51996a..2fde5aae80 100644 --- a/src/library/scala/annotation/ClassfileAnnotation.scala +++ b/src/library/scala/annotation/ClassfileAnnotation.scala @@ -9,7 +9,7 @@ package scala.annotation /** A base class for classfile annotations. These are stored as - * [[http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html#_top Java annotations]]] + * [[http://docs.oracle.com/javase/7/docs/technotes/guides/language/annotations.html#_top Java annotations]]] * in classfiles. * * @author Martin Odersky diff --git a/src/library/scala/annotation/switch.scala b/src/library/scala/annotation/switch.scala index 3734686b27..ee068f50d4 100644 --- a/src/library/scala/annotation/switch.scala +++ b/src/library/scala/annotation/switch.scala @@ -9,8 +9,8 @@ package scala.annotation /** An annotation to be applied to a match expression. If present, * the compiler will verify that the match has been compiled to a - * [[http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc14.html tableswitch]] - * or [[http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc8.html#lookupswitch lookupswitch]] + * [[http://docs.oracle.com/javase/specs/jvms/se5.0/html/Instructions2.doc14.html tableswitch]] + * or [[http://docs.oracle.com/javase/specs/jvms/se5.0/html/Instructions2.doc8.html#lookupswitch lookupswitch]] * and issue an error if it instead compiles into a series of conditional expressions. * Example usage: {{{ diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala index 7b57a91c41..65de60c8fe 100644 --- a/src/library/scala/collection/Iterator.scala +++ b/src/library/scala/collection/Iterator.scala @@ -329,14 +329,16 @@ trait Iterator[+A] extends TraversableOnce[A] { def ++[B >: A](that: => GenTraversableOnce[B]): Iterator[B] = new AbstractIterator[B] { // optimize a little bit to prevent n log n behavior. private var cur : Iterator[B] = self + private var selfExhausted : Boolean = false // since that is by-name, make sure it's only referenced once - // if "val it = that" is inside the block, then hasNext on an empty // iterator will continually reevaluate it. (ticket #3269) lazy val it = that.toIterator // the eq check is to avoid an infinite loop on "x ++ x" - def hasNext = cur.hasNext || ((cur eq self) && { + def hasNext = cur.hasNext || (!selfExhausted && { it.hasNext && { cur = it + selfExhausted = true true } }) diff --git a/src/library/scala/collection/immutable/NumericRange.scala b/src/library/scala/collection/immutable/NumericRange.scala index 65bd9ab6f2..0966fa035f 100644 --- a/src/library/scala/collection/immutable/NumericRange.scala +++ b/src/library/scala/collection/immutable/NumericRange.scala @@ -172,6 +172,13 @@ extends AbstractSeq[T] with IndexedSeq[T] with Serializable { try containsTyped(x.asInstanceOf[T]) catch { case _: ClassCastException => false } + final override def sum[B >: T](implicit num: Numeric[B]): B = { + import num.Ops + if (isEmpty) this.num fromInt 0 + else if (numRangeElements == 1) head + else ((this.num fromInt numRangeElements) * (head + last) / (this.num fromInt 2)) + } + override lazy val hashCode = super.hashCode() override def equals(other: Any) = other match { case x: NumericRange[_] => diff --git a/src/library/scala/collection/parallel/TaskSupport.scala b/src/library/scala/collection/parallel/TaskSupport.scala index 59b75f523f..2eaa861429 100644 --- a/src/library/scala/collection/parallel/TaskSupport.scala +++ b/src/library/scala/collection/parallel/TaskSupport.scala @@ -48,7 +48,7 @@ extends TaskSupport with AdaptiveWorkStealingThreadPoolTasks * By default, parallel collections are parametrized with this task support object, so parallel collections * share the same execution context backend as the rest of the `scala.concurrent` package. */ -class ExecutionContextTaskSupport(val environment: ExecutionContext = scala.concurrent.executionContext) +class ExecutionContextTaskSupport(val environment: ExecutionContext = scala.concurrent.defaultExecutionContext) extends TaskSupport with ExecutionContextTasks diff --git a/src/library/scala/concurrent/ConcurrentPackageObject.scala b/src/library/scala/concurrent/ConcurrentPackageObject.scala index 0f882540f2..d185ade8a4 100644 --- a/src/library/scala/concurrent/ConcurrentPackageObject.scala +++ b/src/library/scala/concurrent/ConcurrentPackageObject.scala @@ -20,8 +20,7 @@ import ConcurrentPackageObject._ abstract class ConcurrentPackageObject { /** A global execution environment for executing lightweight tasks. */ - lazy val executionContext = - new impl.ExecutionContextImpl() + lazy val defaultExecutionContext = new impl.ExecutionContextImpl(null) private val currentExecutionContext = new ThreadLocal[ExecutionContext] @@ -42,7 +41,7 @@ abstract class ConcurrentPackageObject { case Left(t: scala.util.control.ControlThrowable) => Left(new ExecutionException("Boxed ControlThrowable", t)) case Left(t: InterruptedException) => Left(new ExecutionException("Boxed InterruptedException", t)) case Left(e: Error) => Left(new ExecutionException("Boxed Error", e)) - case _ => source + case _ => source } private[concurrent] def resolver[T] = @@ -50,10 +49,10 @@ abstract class ConcurrentPackageObject { /* concurrency constructs */ - def future[T](body: =>T)(implicit execctx: ExecutionContext = executionContext): Future[T] = + def future[T](body: =>T)(implicit execctx: ExecutionContext = defaultExecutionContext): Future[T] = Future[T](body) - def promise[T]()(implicit execctx: ExecutionContext = executionContext): Promise[T] = + def promise[T]()(implicit execctx: ExecutionContext = defaultExecutionContext): Promise[T] = Promise[T]() /** Wraps a block of code into an awaitable object. */ diff --git a/src/library/scala/concurrent/ExecutionContext.scala b/src/library/scala/concurrent/ExecutionContext.scala index 16d9a1f980..e1d4276396 100644 --- a/src/library/scala/concurrent/ExecutionContext.scala +++ b/src/library/scala/concurrent/ExecutionContext.scala @@ -11,7 +11,7 @@ package scala.concurrent import java.util.concurrent.atomic.{ AtomicInteger } -import java.util.concurrent.{ Executors, Future => JFuture, Callable } +import java.util.concurrent.{ Executors, Future => JFuture, Callable, ExecutorService, Executor } import scala.concurrent.util.Duration import scala.concurrent.forkjoin.{ ForkJoinPool, RecursiveTask => FJTask, RecursiveAction, ForkJoinWorkerThread } import scala.collection.generic.CanBuildFrom @@ -36,5 +36,20 @@ trait ExecutionContext { } +/** Contains factory methods for creating execution contexts. + */ +object ExecutionContext { + + implicit def defaultExecutionContext: ExecutionContext = scala.concurrent.defaultExecutionContext + + /** Creates an `ExecutionContext` from the given `ExecutorService`. + */ + def fromExecutorService(e: ExecutorService): ExecutionContext with Executor = new impl.ExecutionContextImpl(e) + + /** Creates an `ExecutionContext` from the given `Executor`. + */ + def fromExecutor(e: Executor): ExecutionContext with Executor = new impl.ExecutionContextImpl(e) + +} diff --git a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala index 9a94bfca4f..52c834359d 100644 --- a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala +++ b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala @@ -10,20 +10,20 @@ package scala.concurrent.impl -import java.util.concurrent.{Callable, ExecutorService, Executors, ThreadFactory} +import java.util.concurrent.{Callable, Executor, ExecutorService, Executors, ThreadFactory} import scala.concurrent.forkjoin._ import scala.concurrent.{ExecutionContext, resolver, Awaitable, body2awaitable} import scala.concurrent.util.{ Duration } -private[scala] class ExecutionContextImpl() extends ExecutionContext { +private[scala] class ExecutionContextImpl(es: AnyRef) extends ExecutionContext with Executor { import ExecutionContextImpl._ - val executorService: AnyRef = getExecutorService + val executorService: AnyRef = if (es eq null) getExecutorService else es // to ensure that the current execution context thread local is properly set - private def executorsThreadFactory = new ThreadFactory { + def executorsThreadFactory = new ThreadFactory { def newThread(r: Runnable) = new Thread(new Runnable { override def run() { currentExecutionContext.set(ExecutionContextImpl.this) @@ -33,7 +33,7 @@ private[scala] class ExecutionContextImpl() extends ExecutionContext { } // to ensure that the current execution context thread local is properly set - private def forkJoinPoolThreadFactory = new ForkJoinPool.ForkJoinWorkerThreadFactory { + def forkJoinPoolThreadFactory = new ForkJoinPool.ForkJoinWorkerThreadFactory { def newThread(fjp: ForkJoinPool) = new ForkJoinWorkerThread(fjp) { override def onStart() { currentExecutionContext.set(ExecutionContextImpl.this) @@ -41,7 +41,7 @@ private[scala] class ExecutionContextImpl() extends ExecutionContext { } } - private def getExecutorService: AnyRef = + def getExecutorService: AnyRef = if (scala.util.Properties.isJavaAtLeast("1.6")) { val vendor = scala.util.Properties.javaVmVendor if ((vendor contains "Oracle") || (vendor contains "Sun") || (vendor contains "Apple")) @@ -62,8 +62,8 @@ private[scala] class ExecutionContextImpl() extends ExecutionContext { } else { fj.execute(runnable) } - case executorService: ExecutorService => - executorService execute runnable + case executor: Executor => + executor execute runnable } def execute[U](body: () => U): Unit = execute(new Runnable { @@ -86,7 +86,7 @@ private[scala] class ExecutionContextImpl() extends ExecutionContext { object ExecutionContextImpl { - private[concurrent] def currentExecutionContext: ThreadLocal[ExecutionContextImpl] = new ThreadLocal[ExecutionContextImpl] { + private[concurrent] def currentExecutionContext: ThreadLocal[ExecutionContext] = new ThreadLocal[ExecutionContext] { override protected def initialValue = null } diff --git a/src/library/scala/reflect/api/Positions.scala b/src/library/scala/reflect/api/Positions.scala index 4c8c33bec8..91f1081b4d 100644 --- a/src/library/scala/reflect/api/Positions.scala +++ b/src/library/scala/reflect/api/Positions.scala @@ -11,7 +11,7 @@ trait Positions { self: Universe => * Typically, positionToAnnotation is the identity, and annotationToPosition returns annot.pos */ type TreeAnnotation // <: { def pos: Position } - val NoTreeAnnotation: TreeAnnotation + def NoTreeAnnotation: TreeAnnotation implicit def positionToAnnotation(pos: Position): TreeAnnotation // = pos def annotationToPosition(annot: TreeAnnotation): Position // = annot.pos def _checkSetAnnotation(tree: Tree, annot: TreeAnnotation): Unit = () // check that annot may overwrite tree.annot diff --git a/src/library/scala/reflect/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala index 6fd83f4821..ab59a4a39a 100755 --- a/src/library/scala/reflect/api/Symbols.scala +++ b/src/library/scala/reflect/api/Symbols.scala @@ -192,7 +192,7 @@ trait Symbols { self: Universe => /** 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): Symbol // needed by LiftCode + def newNestedSymbol(name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol // needed by LiftCode /** Low-level operation to set the symbol's flags * @return the symbol itself diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala index 4ee13adf52..d8180fe029 100644 --- a/src/library/scala/reflect/api/Trees.scala +++ b/src/library/scala/reflect/api/Trees.scala @@ -298,7 +298,6 @@ trait Trees { self: Universe => case ValDef(mods, _, _, _) => if (mods hasModifier Modifier.mutable) "var" else "val" case _ => "" } - // final def hasFlag(mask: Long): Boolean = mods hasFlag mask } /** A packaging, such as `package pid { stats }` diff --git a/src/library/scala/runtime/BoxesRunTime.java b/src/library/scala/runtime/BoxesRunTime.java index b19c8d086c..94047d6f53 100644 --- a/src/library/scala/runtime/BoxesRunTime.java +++ b/src/library/scala/runtime/BoxesRunTime.java @@ -31,17 +31,27 @@ public final class BoxesRunTime { private static final int CHAR = 0, BYTE = 1, SHORT = 2, INT = 3, LONG = 4, FLOAT = 5, DOUBLE = 6, OTHER = 7; + /** We don't need to return BYTE and SHORT, as everything which might + * care widens to INT. + */ private static int typeCode(Object a) { if (a instanceof java.lang.Integer) return INT; - if (a instanceof java.lang.Byte) return BYTE; - if (a instanceof java.lang.Character) return CHAR; - if (a instanceof java.lang.Long) return LONG; if (a instanceof java.lang.Double) return DOUBLE; - if (a instanceof java.lang.Short) return SHORT; + if (a instanceof java.lang.Long) return LONG; + if (a instanceof java.lang.Character) return CHAR; if (a instanceof java.lang.Float) return FLOAT; + if ((a instanceof java.lang.Byte) || (a instanceof java.lang.Short)) return INT; return OTHER; } + private static int eqTypeCode(Number a) { + int code = typeCode(a); + if (code == CHAR) + return OTHER; + else + return code; + } + private static String boxDescription(Object a) { return "" + a.getClass().getSimpleName() + "(" + a + ")"; } @@ -119,15 +129,6 @@ public final class BoxesRunTime /* COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON */ - private static int eqTypeCode(Number a) { - if ((a instanceof java.lang.Integer) || (a instanceof java.lang.Byte)) return INT; - if (a instanceof java.lang.Long) return LONG; - if (a instanceof java.lang.Double) return DOUBLE; - if (a instanceof java.lang.Short) return INT; - if (a instanceof java.lang.Float) return FLOAT; - return OTHER; - } - public static boolean equals(Object x, Object y) { if (x == y) return true; return equals2(x, y); @@ -192,6 +193,9 @@ public final class BoxesRunTime } private static boolean equalsNumChar(java.lang.Number xn, java.lang.Character yc) { + if (yc == null) + return xn == null; + char ch = yc.charValue(); switch (eqTypeCode(xn)) { case INT: @@ -203,9 +207,6 @@ public final class BoxesRunTime case DOUBLE: return xn.doubleValue() == ch; default: - if (xn == null) - return yc == null; - return xn.equals(yc); } } @@ -271,6 +272,31 @@ public final class BoxesRunTime else return a.hashCode(); } + private static int unboxCharOrInt(Object arg1, int code) { + if (code == CHAR) + return ((java.lang.Character) arg1).charValue(); + else + return ((java.lang.Number) arg1).intValue(); + } + private static long unboxCharOrLong(Object arg1, int code) { + if (code == CHAR) + return ((java.lang.Character) arg1).charValue(); + else + return ((java.lang.Number) arg1).longValue(); + } + private static float unboxCharOrFloat(Object arg1, int code) { + if (code == CHAR) + return ((java.lang.Character) arg1).charValue(); + else + return ((java.lang.Number) arg1).floatValue(); + } + private static double unboxCharOrDouble(Object arg1, int code) { + if (code == CHAR) + return ((java.lang.Character) arg1).charValue(); + else + return ((java.lang.Number) arg1).doubleValue(); + } + /* OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS */ /** arg1 + arg2 */ @@ -279,24 +305,16 @@ public final class BoxesRunTime int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); - return boxToInteger(val1 + val2); + return boxToInteger(unboxCharOrInt(arg1, code1) + unboxCharOrInt(arg2, code2)); } if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); - return boxToLong(val1 + val2); + return boxToLong(unboxCharOrLong(arg1, code1) + unboxCharOrLong(arg2, code2)); } if (maxcode <= FLOAT) { - float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue(); - float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue(); - return boxToFloat(val1 + val2); + return boxToFloat(unboxCharOrFloat(arg1, code1) + unboxCharOrFloat(arg2, code2)); } if (maxcode <= DOUBLE) { - double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue(); - double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue(); - return boxToDouble(val1 + val2); + return boxToDouble(unboxCharOrDouble(arg1, code1) + unboxCharOrDouble(arg2, code2)); } throw new NoSuchMethodException(); } @@ -307,24 +325,16 @@ public final class BoxesRunTime int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); - return boxToInteger(val1 - val2); + return boxToInteger(unboxCharOrInt(arg1, code1) - unboxCharOrInt(arg2, code2)); } if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); - return boxToLong(val1 - val2); + return boxToLong(unboxCharOrLong(arg1, code1) - unboxCharOrLong(arg2, code2)); } if (maxcode <= FLOAT) { - float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue(); - float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue(); - return boxToFloat(val1 - val2); + return boxToFloat(unboxCharOrFloat(arg1, code1) - unboxCharOrFloat(arg2, code2)); } if (maxcode <= DOUBLE) { - double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue(); - double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue(); - return boxToDouble(val1 - val2); + return boxToDouble(unboxCharOrDouble(arg1, code1) - unboxCharOrDouble(arg2, code2)); } throw new NoSuchMethodException(); } @@ -335,24 +345,16 @@ public final class BoxesRunTime int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); - return boxToInteger(val1 * val2); + return boxToInteger(unboxCharOrInt(arg1, code1) * unboxCharOrInt(arg2, code2)); } if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); - return boxToLong(val1 * val2); + return boxToLong(unboxCharOrLong(arg1, code1) * unboxCharOrLong(arg2, code2)); } if (maxcode <= FLOAT) { - float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue(); - float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue(); - return boxToFloat(val1 * val2); + return boxToFloat(unboxCharOrFloat(arg1, code1) * unboxCharOrFloat(arg2, code2)); } if (maxcode <= DOUBLE) { - double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue(); - double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue(); - return boxToDouble(val1 * val2); + return boxToDouble(unboxCharOrDouble(arg1, code1) * unboxCharOrDouble(arg2, code2)); } throw new NoSuchMethodException(); } @@ -362,26 +364,16 @@ public final class BoxesRunTime int code1 = typeCode(arg1); int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; - if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); - return boxToInteger(val1 / val2); - } - if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); - return boxToLong(val1 / val2); - } - if (maxcode <= FLOAT) { - float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue(); - float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue(); - return boxToFloat(val1 / val2); - } - if (maxcode <= DOUBLE) { - double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue(); - double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue(); - return boxToDouble(val1 / val2); - } + + if (maxcode <= INT) + return boxToInteger(unboxCharOrInt(arg1, code1) / unboxCharOrInt(arg2, code2)); + if (maxcode <= LONG) + return boxToLong(unboxCharOrLong(arg1, code1) / unboxCharOrLong(arg2, code2)); + if (maxcode <= FLOAT) + return boxToFloat(unboxCharOrFloat(arg1, code1) / unboxCharOrFloat(arg2, code2)); + if (maxcode <= DOUBLE) + return boxToDouble(unboxCharOrDouble(arg1, code1) / unboxCharOrDouble(arg2, code2)); + throw new NoSuchMethodException(); } @@ -390,26 +382,16 @@ public final class BoxesRunTime int code1 = typeCode(arg1); int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; - if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); - return boxToInteger(val1 % val2); - } - if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); - return boxToLong(val1 % val2); - } - if (maxcode <= FLOAT) { - float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue(); - float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue(); - return boxToFloat(val1 % val2); - } - if (maxcode <= DOUBLE) { - double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue(); - double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue(); - return boxToDouble(val1 % val2); - } + + if (maxcode <= INT) + return boxToInteger(unboxCharOrInt(arg1, code1) % unboxCharOrInt(arg2, code2)); + if (maxcode <= LONG) + return boxToLong(unboxCharOrLong(arg1, code1) % unboxCharOrLong(arg2, code2)); + if (maxcode <= FLOAT) + return boxToFloat(unboxCharOrFloat(arg1, code1) % unboxCharOrFloat(arg2, code2)); + if (maxcode <= DOUBLE) + return boxToDouble(unboxCharOrDouble(arg1, code1) % unboxCharOrDouble(arg2, code2)); + throw new NoSuchMethodException(); } @@ -418,24 +400,24 @@ public final class BoxesRunTime int code1 = typeCode(arg1); int code2 = typeCode(arg2); if (code1 <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); + int val1 = unboxCharOrInt(arg1, code1); if (code2 <= INT) { - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); + int val2 = unboxCharOrInt(arg2, code2); return boxToInteger(val1 >> val2); } if (code2 <= LONG) { - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); + long val2 = unboxCharOrLong(arg2, code2); return boxToInteger(val1 >> val2); } } if (code1 <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); + long val1 = unboxCharOrLong(arg1, code1); if (code2 <= INT) { - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); + int val2 = unboxCharOrInt(arg2, code2); return boxToLong(val1 >> val2); } if (code2 <= LONG) { - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); + long val2 = unboxCharOrLong(arg2, code2); return boxToLong(val1 >> val2); } } @@ -447,24 +429,24 @@ public final class BoxesRunTime int code1 = typeCode(arg1); int code2 = typeCode(arg2); if (code1 <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); + int val1 = unboxCharOrInt(arg1, code1); if (code2 <= INT) { - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); + int val2 = unboxCharOrInt(arg2, code2); return boxToInteger(val1 << val2); } if (code2 <= LONG) { - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); + long val2 = unboxCharOrLong(arg2, code2); return boxToInteger(val1 << val2); } } if (code1 <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); + long val1 = unboxCharOrLong(arg1, code1); if (code2 <= INT) { - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); + int val2 = unboxCharOrInt(arg2, code2); return boxToLong(val1 << val2); } if (code2 <= LONG) { - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); + long val2 = unboxCharOrLong(arg2, code2); return boxToLong(val1 << val2); } } @@ -476,24 +458,24 @@ public final class BoxesRunTime int code1 = typeCode(arg1); int code2 = typeCode(arg2); if (code1 <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); + int val1 = unboxCharOrInt(arg1, code1); if (code2 <= INT) { - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); + int val2 = unboxCharOrInt(arg2, code2); return boxToInteger(val1 >>> val2); } if (code2 <= LONG) { - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); + long val2 = unboxCharOrLong(arg2, code2); return boxToInteger(val1 >>> val2); } } if (code1 <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); + long val1 = unboxCharOrLong(arg1, code1); if (code2 <= INT) { - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); + int val2 = unboxCharOrInt(arg2, code2); return boxToLong(val1 >>> val2); } if (code2 <= LONG) { - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); + long val2 = unboxCharOrLong(arg2, code2); return boxToLong(val1 >>> val2); } } @@ -504,19 +486,19 @@ public final class BoxesRunTime public static Object negate(Object arg) throws NoSuchMethodException { int code = typeCode(arg); if (code <= INT) { - int val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).intValue(); + int val = unboxCharOrInt(arg, code); return boxToInteger(-val); } if (code <= LONG) { - long val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).longValue(); + long val = unboxCharOrLong(arg, code); return boxToLong(-val); } if (code <= FLOAT) { - float val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).floatValue(); + float val = unboxCharOrFloat(arg, code); return boxToFloat(-val); } if (code <= DOUBLE) { - double val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).doubleValue(); + double val = unboxCharOrDouble(arg, code); return boxToDouble(-val); } throw new NoSuchMethodException(); @@ -526,20 +508,16 @@ public final class BoxesRunTime public static Object positive(Object arg) throws NoSuchMethodException { int code = typeCode(arg); if (code <= INT) { - int val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).intValue(); - return boxToInteger(+val); + return boxToInteger(+unboxCharOrInt(arg, code)); } if (code <= LONG) { - long val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).longValue(); - return boxToLong(+val); + return boxToLong(+unboxCharOrLong(arg, code)); } if (code <= FLOAT) { - float val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).floatValue(); - return boxToFloat(+val); + return boxToFloat(+unboxCharOrFloat(arg, code)); } if (code <= DOUBLE) { - double val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).doubleValue(); - return boxToDouble(+val); + return boxToDouble(+unboxCharOrDouble(arg, code)); } throw new NoSuchMethodException(); } @@ -547,72 +525,60 @@ public final class BoxesRunTime /** arg1 & arg2 */ public static Object takeAnd(Object arg1, Object arg2) throws NoSuchMethodException { if ((arg1 instanceof Boolean) || (arg2 instanceof Boolean)) { - if (!((arg1 instanceof Boolean) && (arg2 instanceof Boolean))) { + if ((arg1 instanceof Boolean) && (arg2 instanceof Boolean)) + return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() & ((java.lang.Boolean) arg2).booleanValue()); + else throw new NoSuchMethodException(); - } - return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() & ((java.lang.Boolean) arg2).booleanValue()); } int code1 = typeCode(arg1); int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; - if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); - return boxToInteger(val1 & val2); - } - if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); - return boxToLong(val1 & val2); - } + + if (maxcode <= INT) + return boxToInteger(unboxCharOrInt(arg1, code1) & unboxCharOrInt(arg2, code2)); + if (maxcode <= LONG) + return boxToLong(unboxCharOrLong(arg1, code1) & unboxCharOrLong(arg2, code2)); + throw new NoSuchMethodException(); } /** arg1 | arg2 */ public static Object takeOr(Object arg1, Object arg2) throws NoSuchMethodException { if ((arg1 instanceof Boolean) || (arg2 instanceof Boolean)) { - if (!((arg1 instanceof Boolean) && (arg2 instanceof Boolean))) { + if ((arg1 instanceof Boolean) && (arg2 instanceof Boolean)) + return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() | ((java.lang.Boolean) arg2).booleanValue()); + else throw new NoSuchMethodException(); - } - return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() | ((java.lang.Boolean) arg2).booleanValue()); } int code1 = typeCode(arg1); int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; - if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); - return boxToInteger(val1 | val2); - } - if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); - return boxToLong(val1 | val2); - } + + if (maxcode <= INT) + return boxToInteger(unboxCharOrInt(arg1, code1) | unboxCharOrInt(arg2, code2)); + if (maxcode <= LONG) + return boxToLong(unboxCharOrLong(arg1, code1) | unboxCharOrLong(arg2, code2)); + throw new NoSuchMethodException(); } /** arg1 ^ arg2 */ public static Object takeXor(Object arg1, Object arg2) throws NoSuchMethodException { if ((arg1 instanceof Boolean) || (arg2 instanceof Boolean)) { - if (!((arg1 instanceof Boolean) && (arg2 instanceof Boolean))) { + if ((arg1 instanceof Boolean) && (arg2 instanceof Boolean)) + return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() ^ ((java.lang.Boolean) arg2).booleanValue()); + else throw new NoSuchMethodException(); - } - return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() ^ ((java.lang.Boolean) arg2).booleanValue()); } int code1 = typeCode(arg1); int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; - if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); - return boxToInteger(val1 ^ val2); - } - if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); - return boxToLong(val1 ^ val2); - } + + if (maxcode <= INT) + return boxToInteger(unboxCharOrInt(arg1, code1) ^ unboxCharOrInt(arg2, code2)); + if (maxcode <= LONG) + return boxToLong(unboxCharOrLong(arg1, code1) ^ unboxCharOrLong(arg2, code2)); + throw new NoSuchMethodException(); } @@ -636,12 +602,10 @@ public final class BoxesRunTime public static Object complement(Object arg) throws NoSuchMethodException { int code = typeCode(arg); if (code <= INT) { - int val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).intValue(); - return boxToInteger(~val); + return boxToInteger(~unboxCharOrInt(arg, code)); } if (code <= LONG) { - long val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).longValue(); - return boxToLong(~val); + return boxToLong(~unboxCharOrLong(arg, code)); } throw new NoSuchMethodException(); } @@ -667,23 +631,23 @@ public final class BoxesRunTime int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); + int val1 = unboxCharOrInt(arg1, code1); + int val2 = unboxCharOrInt(arg2, code2); return boxToBoolean(val1 < val2); } if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); + long val1 = unboxCharOrLong(arg1, code1); + long val2 = unboxCharOrLong(arg2, code2); return boxToBoolean(val1 < val2); } if (maxcode <= FLOAT) { - float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue(); - float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue(); + float val1 = unboxCharOrFloat(arg1, code1); + float val2 = unboxCharOrFloat(arg2, code2); return boxToBoolean(val1 < val2); } if (maxcode <= DOUBLE) { - double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue(); - double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue(); + double val1 = unboxCharOrDouble(arg1, code1); + double val2 = unboxCharOrDouble(arg2, code2); return boxToBoolean(val1 < val2); } throw new NoSuchMethodException(); @@ -694,23 +658,23 @@ public final class BoxesRunTime int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); + int val1 = unboxCharOrInt(arg1, code1); + int val2 = unboxCharOrInt(arg2, code2); return boxToBoolean(val1 <= val2); } if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); + long val1 = unboxCharOrLong(arg1, code1); + long val2 = unboxCharOrLong(arg2, code2); return boxToBoolean(val1 <= val2); } if (maxcode <= FLOAT) { - float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue(); - float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue(); + float val1 = unboxCharOrFloat(arg1, code1); + float val2 = unboxCharOrFloat(arg2, code2); return boxToBoolean(val1 <= val2); } if (maxcode <= DOUBLE) { - double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue(); - double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue(); + double val1 = unboxCharOrDouble(arg1, code1); + double val2 = unboxCharOrDouble(arg2, code2); return boxToBoolean(val1 <= val2); } throw new NoSuchMethodException(); @@ -721,23 +685,23 @@ public final class BoxesRunTime int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); + int val1 = unboxCharOrInt(arg1, code1); + int val2 = unboxCharOrInt(arg2, code2); return boxToBoolean(val1 >= val2); } if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); + long val1 = unboxCharOrLong(arg1, code1); + long val2 = unboxCharOrLong(arg2, code2); return boxToBoolean(val1 >= val2); } if (maxcode <= FLOAT) { - float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue(); - float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue(); + float val1 = unboxCharOrFloat(arg1, code1); + float val2 = unboxCharOrFloat(arg2, code2); return boxToBoolean(val1 >= val2); } if (maxcode <= DOUBLE) { - double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue(); - double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue(); + double val1 = unboxCharOrDouble(arg1, code1); + double val2 = unboxCharOrDouble(arg2, code2); return boxToBoolean(val1 >= val2); } throw new NoSuchMethodException(); @@ -748,33 +712,30 @@ public final class BoxesRunTime int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); + int val1 = unboxCharOrInt(arg1, code1); + int val2 = unboxCharOrInt(arg2, code2); return boxToBoolean(val1 > val2); } if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); + long val1 = unboxCharOrLong(arg1, code1); + long val2 = unboxCharOrLong(arg2, code2); return boxToBoolean(val1 > val2); } if (maxcode <= FLOAT) { - float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue(); - float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue(); + float val1 = unboxCharOrFloat(arg1, code1); + float val2 = unboxCharOrFloat(arg2, code2); return boxToBoolean(val1 > val2); } if (maxcode <= DOUBLE) { - double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue(); - double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue(); + double val1 = unboxCharOrDouble(arg1, code1); + double val2 = unboxCharOrDouble(arg2, code2); return boxToBoolean(val1 > val2); } throw new NoSuchMethodException(); } - + public static boolean isBoxedNumberOrBoolean(Object arg) { - if (arg instanceof java.lang.Boolean) - return true; - else - return isBoxedNumber(arg); + return (arg instanceof java.lang.Boolean) || isBoxedNumber(arg); } public static boolean isBoxedNumber(Object arg) { return ( |