diff options
Diffstat (limited to 'src/reflect/scala/reflect/internal/Symbols.scala')
-rw-r--r-- | src/reflect/scala/reflect/internal/Symbols.scala | 420 |
1 files changed, 181 insertions, 239 deletions
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 16b2a23c23..854849d27c 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -7,7 +7,7 @@ package scala package reflect package internal -import scala.collection.{ mutable, immutable } +import scala.collection.immutable import scala.collection.mutable.ListBuffer import util.{ Statistics, shortClassOfInstance } import Flags._ @@ -34,9 +34,13 @@ trait Symbols extends api.Symbols { self: SymbolTable => def recursionTable = _recursionTable def recursionTable_=(value: immutable.Map[Symbol, Int]) = _recursionTable = value + @deprecated("Global existential IDs no longer used", "2.12.1") private var existentialIds = 0 + @deprecated("Global existential IDs no longer used", "2.12.1") protected def nextExistentialId() = { existentialIds += 1; existentialIds } - protected def freshExistentialName(suffix: String) = newTypeName("_" + nextExistentialId() + suffix) + @deprecated("Use overload that accepts an id", "2.12.1") + protected def freshExistentialName(suffix: String): TypeName = freshExistentialName(suffix, nextExistentialId()) + protected def freshExistentialName(suffix: String, id: Int): TypeName = newTypeName("_" + id + suffix) // Set the fields which point companions at one another. Returns the module. def connectModuleToClass(m: ModuleSymbol, moduleClass: ClassSymbol): ModuleSymbol = { @@ -96,12 +100,19 @@ trait Symbols extends api.Symbols { self: SymbolTable => def isByNameParam: Boolean = this.isValueParameter && (this hasFlag BYNAMEPARAM) def isImplementationArtifact: Boolean = (this hasFlag BRIDGE) || (this hasFlag VBRIDGE) || (this hasFlag ARTIFACT) def isJava: Boolean = isJavaDefined - def isVal: Boolean = isTerm && !isModule && !isMethod && !isMutable - def isVar: Boolean = isTerm && !isModule && !isMethod && !isLazy && isMutable + + def isField: Boolean = isTerm && !isModule && (!isMethod || owner.isTrait && isAccessor) + def isMutableVal = if (owner.isTrait) !hasFlag(STABLE) else isMutable + def isVal: Boolean = isField && !isMutableVal + def isVar: Boolean = isField && !isLazy && isMutableVal + def isAbstract: Boolean = isAbstractClass || isDeferred || isAbstractType def isPrivateThis = (this hasFlag PRIVATE) && (this hasFlag LOCAL) def isProtectedThis = (this hasFlag PROTECTED) && (this hasFlag LOCAL) + def isJavaEnum: Boolean = hasJavaEnumFlag + def isJavaAnnotation: Boolean = hasJavaAnnotationFlag + def newNestedSymbol(name: Name, pos: Position, newFlags: Long, isClass: Boolean): Symbol = name match { case n: TermName => newTermSymbol(n, pos, newFlags) case n: TypeName => if (isClass) newClassSymbol(n, pos, newFlags) else newNonClassSymbol(n, pos, newFlags) @@ -184,11 +195,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => protected def newStubSymbol(owner: Symbol, name: Name, - missingMessage: String, - isPackage: Boolean = false): Symbol = { + missingMessage: String): Symbol = { name match { - case n: TypeName => if (isPackage) new StubPackageClassSymbol(owner, n, missingMessage) - else new StubClassSymbol(owner, n, missingMessage) + case n: TypeName => new StubClassSymbol(owner, n, missingMessage) case _ => new StubTermSymbol(owner, name.toTermName, missingMessage) } } @@ -316,9 +325,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => def newClassConstructor(pos: Position): MethodSymbol = newConstructor(pos) setInfo MethodType(Nil, this.tpe) - def newLinkedModule(clazz: Symbol, newFlags: Long = 0L): ModuleSymbol = { - val m = newModuleSymbol(clazz.name.toTermName, clazz.pos, MODULE | newFlags) - connectModuleToClass(m, clazz.asInstanceOf[ClassSymbol]) + def newLinkedModule(moduleClass: Symbol, newFlags: Long = 0L): ModuleSymbol = { + val m = newModuleSymbol(moduleClass.name.toTermName, moduleClass.pos, MODULE | newFlags) + connectModuleToClass(m, moduleClass.asInstanceOf[ClassSymbol]) } final def newModule(name: TermName, pos: Position = NoPosition, newFlags0: Long = 0L): ModuleSymbol = { val newFlags = newFlags0 | MODULE @@ -338,17 +347,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def newImport(pos: Position): TermSymbol = newTermSymbol(nme.IMPORT, pos) - def newModuleVarSymbol(accessor: Symbol): TermSymbol = { - val newName = nme.moduleVarName(accessor.name.toTermName) - val newFlags = MODULEVAR | ( if (this.isClass) PrivateLocal | SYNTHETIC else 0 ) - val newInfo = accessor.tpe.finalResultType - val mval = newVariable(newName, accessor.pos.focus, newFlags.toLong) addAnnotation VolatileAttr - - if (this.isClass) - mval setInfoAndEnter newInfo - else - mval setInfo newInfo - } final def newModuleSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol = newTermSymbol(name, pos, newFlags).asInstanceOf[ModuleSymbol] @@ -465,8 +463,11 @@ 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) | GADT_SKOLEM_FLAGS) setInfo info + @deprecated("Use overload that accepts an id", "2.12.1") final def freshExistential(suffix: String): TypeSymbol = newExistential(freshExistentialName(suffix), pos) + final def freshExistential(suffix: String, id: Int): TypeSymbol = + newExistential(freshExistentialName(suffix, id), pos) /** Type skolems are type parameters ''seen from the inside'' * Assuming a polymorphic method m[T], its type is a PolyType which has a TypeParameter @@ -496,10 +497,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def newAnonymousFunctionValue(pos: Position, newFlags: Long = 0L): TermSymbol = newTermSymbol(nme.ANON_FUN_NAME, pos, SYNTHETIC | newFlags) setInfo NoType - def newImplClass(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol = { - newClassSymbol(name, pos, newFlags | IMPLCLASS) - } - /** Refinement types P { val x: String; type T <: Number } * also have symbols, they are refinementClasses */ @@ -516,9 +513,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => * failure to the point when that name is used for something, which is * often to the point of never. */ - def newStubSymbol(name: Name, missingMessage: String, isPackage: Boolean = false): Symbol = { + def newStubSymbol(name: Name, missingMessage: String): Symbol = { // Invoke the overriden `newStubSymbol` in Global that gives us access to typer - Symbols.this.newStubSymbol(this, name, missingMessage, isPackage) + Symbols.this.newStubSymbol(this, name, missingMessage) } /** Given a field, construct a term symbol that represents the source construct that gave rise the field */ @@ -606,7 +603,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => def isAnonymousClass = false def isCaseClass = false def isConcreteClass = false - def isImplClass = false // the implementation class of a trait + @deprecated("trait implementation classes have been removed in Scala 2.12", "2.12.0") + def isImplClass = false def isJavaInterface = false def isNumericValueClass = false def isPrimitiveValueClass = false @@ -683,7 +681,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => isClass && isFinal && loop(typeParams) } - final def isLazyAccessor = isLazy && lazyAccessor != NoSymbol final def isOverridableMember = !(isClass || isEffectivelyFinal) && safeOwner.isClass /** Does this symbol denote a wrapper created by the repl? */ @@ -746,7 +743,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => def setFlag(mask: Long): this.type = { _rawflags |= mask ; this } def resetFlag(mask: Long): this.type = { _rawflags &= ~mask ; this } - def resetFlags() { rawflags &= TopLevelCreationFlags } + def resetFlags() { rawflags = 0 } /** Default implementation calls the generic string function, which * will print overloaded flags as <flag1/flag2/flag3>. Subclasses @@ -774,10 +771,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def hasGetter = isTerm && nme.isLocalName(name) /** - * Nested modules which have no static owner when ModuleDefs are eliminated (refchecks) are - * given the lateMETHOD flag, which makes them appear as methods after refchecks. + * Nested modules with a non-static owner receive the METHOD flag during UnCurry's info transform. + * (They are replaced by a ClassDef and DefDef for the module accessor during the fields phase.) * - * Note: the lateMETHOD flag is added lazily in the info transformer of the RefChecks phase. + * Note: the METHOD flag is added lazily in the info transformer of the UnCurry phase. * This means that forcing the `sym.info` may change the value of `sym.isMethod`. Forcing the * info is in the responsibility of the caller. Doing it eagerly here was tried (0ccdb151f) but * has proven to lead to bugs (SI-8907). @@ -821,14 +818,14 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isDerivedValueClass = isClass && !hasFlag(PACKAGE | TRAIT) && - info.firstParent.typeSymbol == AnyValClass && !isPrimitiveValueClass + !phase.erasedTypes && info.firstParent.typeSymbol == AnyValClass && !isPrimitiveValueClass final def isMethodWithExtension = isMethod && owner.isDerivedValueClass && !isParamAccessor && !isConstructor && !hasFlag(SUPERACCESSOR) && !isMacro && !isSpecialized final def isAnonymousFunction = isSynthetic && (name containsName tpnme.ANON_FUN_NAME) final def isDelambdafyFunction = isSynthetic && (name containsName tpnme.DELAMBDAFY_LAMBDA_CLASS_NAME) - final def isDelambdafyTarget = isArtifact && isMethod && (name containsName tpnme.ANON_FUN_NAME) + final def isDelambdafyTarget = isArtifact && isMethod && hasAttachment[DelambdafyTarget.type] final def isDefinedInPackage = effectiveOwner.isPackageClass final def needsFlatClasses = phase.flatClasses && rawowner != NoSymbol && !rawowner.isPackageClass @@ -853,6 +850,12 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ def skipPackageObject: Symbol = this + /** The package object symbol corresponding to this package or package class symbol, or NoSymbol otherwise */ + def packageObject: Symbol = + if (isPackageClass) tpe.packageObject + else if (hasPackageFlag) moduleClass.packageObject + else NoSymbol + /** If this is a constructor, its owner: otherwise this. */ final def skipConstructor: Symbol = if (isConstructor) owner else this @@ -886,21 +889,26 @@ trait Symbols extends api.Symbols { self: SymbolTable => ) } - def isStrictFP = hasAnnotation(ScalaStrictFPAttr) || (enclClass hasAnnotation ScalaStrictFPAttr) - def isSerializable = info.baseClasses.exists(p => p == SerializableClass || p == JavaSerializableClass) - def hasBridgeAnnotation = hasAnnotation(BridgeClass) - def isDeprecated = hasAnnotation(DeprecatedAttr) - def deprecationMessage = getAnnotation(DeprecatedAttr) flatMap (_ stringArg 0) - def deprecationVersion = getAnnotation(DeprecatedAttr) flatMap (_ stringArg 1) - def deprecatedParamName = getAnnotation(DeprecatedNameAttr) flatMap (_ symbolArg 0) + def isStrictFP = hasAnnotation(ScalaStrictFPAttr) || (enclClass hasAnnotation ScalaStrictFPAttr) + def isSerializable = info.baseClasses.exists(p => p == SerializableClass || p == JavaSerializableClass) + def hasBridgeAnnotation = hasAnnotation(BridgeClass) + def isDeprecated = hasAnnotation(DeprecatedAttr) + def deprecationMessage = getAnnotation(DeprecatedAttr) flatMap (_ stringArg 0) + def deprecationVersion = getAnnotation(DeprecatedAttr) flatMap (_ stringArg 1) + def deprecatedParamName = getAnnotation(DeprecatedNameAttr) flatMap (_ symbolArg 0 orElse Some(nme.NO_NAME)) + def deprecatedParamVersion = getAnnotation(DeprecatedNameAttr) flatMap (_ stringArg 1) def hasDeprecatedInheritanceAnnotation - = hasAnnotation(DeprecatedInheritanceAttr) + = hasAnnotation(DeprecatedInheritanceAttr) def deprecatedInheritanceMessage - = getAnnotation(DeprecatedInheritanceAttr) flatMap (_ stringArg 0) + = getAnnotation(DeprecatedInheritanceAttr) flatMap (_ stringArg 0) + def deprecatedInheritanceVersion + = getAnnotation(DeprecatedInheritanceAttr) flatMap (_ stringArg 1) def hasDeprecatedOverridingAnnotation - = hasAnnotation(DeprecatedOverridingAttr) + = hasAnnotation(DeprecatedOverridingAttr) def deprecatedOverridingMessage - = getAnnotation(DeprecatedOverridingAttr) flatMap (_ stringArg 0) + = getAnnotation(DeprecatedOverridingAttr) flatMap (_ stringArg 0) + def deprecatedOverridingVersion + = getAnnotation(DeprecatedOverridingAttr) flatMap (_ stringArg 1) // !!! when annotation arguments are not literal strings, but any sort of // assembly of strings, there is a fair chance they will turn up here not as @@ -909,10 +917,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => // string. So this needs attention. For now the fact that migration is // private[scala] ought to provide enough protection. def hasMigrationAnnotation = hasAnnotation(MigrationAnnotationClass) - def migrationMessage = getAnnotation(MigrationAnnotationClass) flatMap { _.stringArg(0) } - def migrationVersion = getAnnotation(MigrationAnnotationClass) flatMap { _.stringArg(1) } - def elisionLevel = getAnnotation(ElidableMethodClass) flatMap { _.intArg(0) } - def implicitNotFoundMsg = getAnnotation(ImplicitNotFoundClass) flatMap { _.stringArg(0) } + def migrationMessage = getAnnotation(MigrationAnnotationClass) flatMap { _.stringArg(0) } + def migrationVersion = getAnnotation(MigrationAnnotationClass) flatMap { _.stringArg(1) } + def elisionLevel = getAnnotation(ElidableMethodClass) flatMap { _.intArg(0) } + def implicitNotFoundMsg = getAnnotation(ImplicitNotFoundClass) flatMap { _.stringArg(0) } + def implicitAmbiguousMsg = getAnnotation(ImplicitAmbiguousClass) flatMap { _.stringArg(0) } def isCompileTimeOnly = hasAnnotation(CompileTimeOnlyAttr) def compileTimeOnlyMessage = getAnnotation(CompileTimeOnlyAttr) flatMap (_ stringArg 0) @@ -923,6 +932,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Is this symbol an accessor method for outer? */ final def isOuterField = isArtifact && (unexpandedName == nme.OUTER_LOCAL) + /** Is this symbol an outer parameter in a constructor */ + final def isOuterParam = isParameter && owner.isConstructor && (name == nme.OUTER_ARG || name == nme.OUTER) + /** Does this symbol denote a stable value, ignoring volatility? * * Stability and volatility are checked separately to allow volatile paths in patterns that amount to equality checks. SI-6815 @@ -947,21 +959,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isCaseCopy = isMethod && owner.isCase && isSynthetic && name == nme.copy - /** Is this symbol a trait which needs an implementation class? */ - final def needsImplClass = ( - isTrait - && (!isInterface || hasFlag(lateINTERFACE)) - && !isImplClass - ) - - /** Is this a symbol which exists only in the implementation class, not in its trait? */ - final def isImplOnly = isPrivate || ( - (owner.isTrait || owner.isImplClass) && ( - hasAllFlags(LIFTED | MODULE | METHOD) - || isConstructor - || hasFlag(notPRIVATE | LIFTED) && !hasFlag(ACCESSOR | SUPERACCESSOR | MODULE) - ) - ) final def isModuleVar = hasFlag(MODULEVAR) /** @@ -985,10 +982,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => * method `owner` returns the class C. * * Why not make a stable version of `isStatic`? Maybe some parts of the compiler depend on the - * current implementation. For example - * trait T { def foo = 1 } - * The method `foo` in the implementation class T$impl will be `isStatic`, because trait - * impl classes get the `lateMODULE` flag (T$impl.isStaticOwner is true). + * current implementation. */ def isStatic = (this hasFlag STATIC) || owner.isStaticOwner @@ -998,7 +992,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Is this symbol a static member of its class? (i.e. needs to be implemented as a Java static?) */ final def isStaticMember: Boolean = - hasFlag(STATIC) || owner.isImplClass + hasFlag(STATIC) /** Does this symbol denote a class that defines static symbols? */ final def isStaticOwner: Boolean = @@ -1008,7 +1002,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => private def isNotOverridden = ( owner.isClass && ( owner.isEffectivelyFinal - || owner.isSealed && owner.children.forall(c => c.isEffectivelyFinal && (overridingSymbol(c) == NoSymbol)) + || (owner.isSealed && owner.sealedChildren.forall(c => c.isEffectivelyFinal && (overridingSymbol(c) == NoSymbol))) ) ) @@ -1016,10 +1010,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isEffectivelyFinal: Boolean = ( (this hasFlag FINAL | PACKAGE) || isModuleOrModuleClass && (isTopLevel || !settings.overrideObjects) - || isTerm && ( - isPrivate - || isLocalToBlock - ) + || isTerm && (isPrivate || isLocalToBlock || (hasAllFlags(notPRIVATE | METHOD) && !hasFlag(DEFERRED))) + || isClass && originalOwner.isTerm && children.isEmpty // we track known subclasses of term-owned classes, use that infer finality ) /** Is this symbol effectively final or a concrete term member of sealed class whose children do not override it */ final def isEffectivelyFinalOrNotOverridden: Boolean = isEffectivelyFinal || (isTerm && !isDeferred && isNotOverridden) @@ -1028,7 +1020,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isTopLevel = owner.isPackageClass /** Is this symbol defined in a block? */ - @deprecated("Use isLocalToBlock instead", "2.11.0") + @deprecated("use isLocalToBlock instead", "2.11.0") final def isLocal: Boolean = owner.isTerm /** Is this symbol defined in a block? */ @@ -1097,7 +1089,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => // parent LowPriorityImplicits. See comment in c5441dc for more elaboration. // Since the fix for SI-7335 Predef parents must be defined in Predef.scala, and we should not // get here anymore. - devWarning(s"calling Symbol#exists with sourcefile based symbol loader may give incorrect results."); + devWarning(s"calling Symbol#exists with sourcefile based symbol loader may give incorrect results.") } rawInfo load this @@ -1244,7 +1236,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => // ------ name attribute -------------------------------------------------------------- - @deprecated("Use unexpandedName", "2.11.0") def originalName: Name = unexpandedName + @deprecated("use unexpandedName", "2.11.0") def originalName: Name = unexpandedName /** If this symbol has an expanded name, its original (unexpanded) name, * otherwise the name itself. @@ -1271,7 +1263,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => def needsModuleSuffix = ( hasModuleFlag && !isMethod - && !isImplClass && !isJavaDefined ) /** These should be moved somewhere like JavaPlatform. @@ -1344,9 +1335,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => protected def createPackageObjectClassSymbol(pos: Position, newFlags: Long): PackageObjectClassSymbol = new PackageObjectClassSymbol(this, pos) initFlags newFlags - protected def createImplClassSymbol(name: TypeName, pos: Position, newFlags: Long): ClassSymbol = - new ClassSymbol(this, pos, name) with ImplClassSymbol initFlags newFlags - protected def createMethodSymbol(name: TermName, pos: Position, newFlags: Long): MethodSymbol = new MethodSymbol(this, pos, name) initFlags newFlags @@ -1385,8 +1373,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => createPackageObjectClassSymbol(pos, newFlags) else if ((newFlags & MODULE) != 0) createModuleClassSymbol(name, pos, newFlags) - else if ((newFlags & IMPLCLASS) != 0) - createImplClassSymbol(name, pos, newFlags) else createClassSymbol(name, pos, newFlags) } @@ -1561,7 +1547,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => def setInfo(info: Type): this.type = { info_=(info); this } /** Modifies this symbol's info in place. */ def modifyInfo(f: Type => Type): this.type = setInfo(f(info)) - /** Substitute second list of symbols for first in current info. */ + /** Substitute second list of symbols for first in current info. + * + * NOTE: this discards the type history (uses setInfo) + */ def substInfo(syms0: List[Symbol], syms1: List[Symbol]): this.type = if (syms0.isEmpty) this else modifyInfo(_.substSym(syms0, syms1)) @@ -1719,7 +1708,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => * * - packageobjects (follows namer) * - superaccessors (follows typer) - * - lazyvals (follows erasure) + * - lambdaLift (follows erasure) * - null */ private def unsafeTypeParamPhase = { @@ -1969,7 +1958,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => result } -// ------ cloneing ------------------------------------------------------------------- +// ------ cloning ------------------------------------------------------------------- /** A clone of this symbol. */ final def cloneSymbol: TypeOfClonedSymbol = @@ -2034,7 +2023,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ def thisSym: Symbol = this - def hasSelfType = thisSym.tpeHK != this.tpeHK + def hasSelfType = (thisSym ne this) && (typeOfThis.typeConstructor ne typeConstructor) /** The type of `this` in a class, or else the type of the symbol itself. */ def typeOfThis = thisSym.tpe_* @@ -2068,18 +2057,16 @@ trait Symbols extends api.Symbols { self: SymbolTable => } } } - private final def caseFieldAccessorsUnsorted: List[Symbol] = - (info.decls filter (_.isCaseAccessorMethod)).toList + private final def caseFieldAccessorsUnsorted: List[Symbol] = info.decls.toList.filter(_.isCaseAccessorMethod) - final def constrParamAccessors: List[Symbol] = - info.decls.filter(sym => !sym.isMethod && sym.isParamAccessor).toList + final def constrParamAccessors: List[Symbol] = info.decls.toList.filter(sym => !sym.isMethod && sym.isParamAccessor) /** The symbol accessed by this accessor (getter or setter) function. */ final def accessed: Symbol = { assert(hasAccessorFlag, this) val localField = owner.info decl localName - if (localField == NoSymbol && this.hasFlag(MIXEDIN)) { + if (localField == NoSymbol && this.hasFlag(MIXEDIN)) { // TODO: fields phase does not (yet?) add MIXEDIN in setMixedinAccessorFlags // SI-8087: private[this] fields don't have a `localName`. When searching the accessed field // for a mixin accessor of such a field, we need to look for `name` instead. // The phase travel ensures that the field is found (`owner` is the trait class symbol, the @@ -2095,12 +2082,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ def sourceModule: Symbol = NoSymbol - /** The implementation class of a trait. If available it will be the - * symbol with the same owner, and the name of this symbol with $class - * appended to it. - */ - final def implClass: Symbol = owner.info.decl(tpnme.implClassName(name)) - /** The class that is logically an outer class of given `clazz`. * This is the enclosing class, except for classes defined locally to constructors, * where it is the outer class of the enclosing class. @@ -2119,14 +2100,21 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ def alias: Symbol = NoSymbol - /** For a lazy value, its lazy accessor. NoSymbol for all others. */ + @deprecated("No longer applicable, as lazy vals are not desugared until the fields phase", "2.12.0") // used by scala-refactoring def lazyAccessor: Symbol = NoSymbol - /** If this is a lazy value, the lazy accessor; otherwise this symbol. */ - def lazyAccessorOrSelf: Symbol = if (isLazy) lazyAccessor else this + @deprecated("No longer applicable, as lazy vals are not desugared until the fields phase", "2.12.0") + def lazyAccessorOrSelf: Symbol = NoSymbol - /** If this is an accessor, the accessed symbol. Otherwise, this symbol. */ - def accessedOrSelf: Symbol = if (hasAccessorFlag) accessed else this + /** `accessed`, if this is an accessor that should have an underlying field. Otherwise, `this`. + * Note that a "regular" accessor in a trait does not have a field, as an interface cannot define a field. + * "non-regular" vals are: early initialized or lazy vals. + * Eventually, we should delay introducing symbols for all val/vars until the fields (or lazyvals) phase, + * as they are an implementation detail that's irrelevant to type checking. + */ + def accessedOrSelf: Symbol = + if (hasAccessorFlag && (!owner.isTrait || hasFlag(PRESUPER))) accessed + else this /** For an outer accessor: The class from which the outer originates. * For all other symbols: NoSymbol @@ -2204,7 +2192,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def logicallyEnclosingMember: Symbol = if (isLocalDummy) enclClass.primaryConstructor else if (isMethod || isClass || this == NoSymbol) this - else if (this == NoSymbol) { devWarningDumpStack("NoSymbol.logicallyEnclosingMember", 15); this } else owner.logicallyEnclosingMember /** The top-level class containing this symbol. */ @@ -2262,7 +2249,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => * to the class. As presently implemented this potentially returns class for * any symbol except NoSymbol. */ - def companionClass: Symbol = flatOwnerInfo.decl(name.toTypeName).suchThat(_ isCoDefinedWith this) + def companionClass: Symbol = flatOwnerInfo.decl(name.toTypeName).suchThat(d => d.isClass && d.isCoDefinedWith(this)) /** For a class: the module or case class factory with the same name in the same package. * For all others: NoSymbol @@ -2304,16 +2291,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => owner.rawInfo } - /** If this symbol is an implementation class, its interface, otherwise the symbol itself - * The method follows two strategies to determine the interface. - * - during or after erasure, it takes the last parent of the implementation class - * (which is always the interface, by convention) - * - before erasure, it looks up the interface name in the scope of the owner of the class. - * This only works for implementation classes owned by other classes or traits. - * !!! Why? - */ - def toInterface: Symbol = this - /** The module class corresponding to this module. */ def moduleClass: Symbol = NoSymbol @@ -2422,7 +2399,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => Nil ) - @deprecated("Use `superSymbolIn` instead", "2.11.0") + @deprecated("use `superSymbolIn` instead", "2.11.0") final def superSymbol(base: Symbol): Symbol = superSymbolIn(base) /** The symbol accessed by a super in the definition of this symbol when @@ -2433,14 +2410,13 @@ trait Symbols extends api.Symbols { self: SymbolTable => var bcs = base.info.baseClasses dropWhile (owner != _) drop 1 var sym: Symbol = NoSymbol while (!bcs.isEmpty && sym == NoSymbol) { - if (!bcs.head.isImplClass) - sym = matchingSymbol(bcs.head, base.thisType).suchThat(!_.isDeferred) + sym = matchingSymbol(bcs.head, base.thisType).suchThat(!_.isDeferred) bcs = bcs.tail } sym } - @deprecated("Use `getterIn` instead", "2.11.0") + @deprecated("use `getterIn` instead", "2.11.0") final def getter(base: Symbol): Symbol = getterIn(base) /** The getter of this value or setter definition in class `base`, or NoSymbol if none exists. */ @@ -2451,7 +2427,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => def setterName: TermName = name.setterName def localName: TermName = name.localName - @deprecated("Use `setterIn` instead", "2.11.0") + @deprecated("use `setterIn` instead", "2.11.0") final def setter(base: Symbol, hasExpandedName: Boolean = needsExpandedSetterName): Symbol = setterIn(base, hasExpandedName) @@ -2495,14 +2471,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ final def makeNotPrivate(base: Symbol) { if (this.isPrivate) { - setFlag(notPRIVATE) - // Marking these methods final causes problems for proxies which use subclassing. If people - // write their code with no usage of final, we probably shouldn't introduce it ourselves - // unless we know it is safe. ... Unfortunately if they aren't marked final the inliner - // thinks it can't inline them. So once again marking lateFINAL, and in genjvm we no longer - // generate ACC_FINAL on "final" methods which are actually lateFINAL. - if (isMethod && !isDeferred) - setFlag(lateFINAL) + setFlag(notPRIVATE) // this makes it effectively final (isEffectivelyFinal) + // don't set FINAL -- methods not marked final by user should not end up final in bytecode + // inliner will know it's effectively final (notPRIVATE non-deferred method) if (!isStaticModule && !isClassConstructor) { expandName(base) if (isModule) moduleClass.makeNotPrivate(base) @@ -2535,14 +2506,15 @@ trait Symbols extends api.Symbols { self: SymbolTable => def associatedFile: AbstractFile = enclosingTopLevelClass.associatedFile def associatedFile_=(f: AbstractFile) { abort("associatedFile_= inapplicable for " + this) } - /** If this is a sealed class, its known direct subclasses. + /** If this is a sealed or local class, its known direct subclasses. * Otherwise, the empty set. */ def children: Set[Symbol] = Set() + final def sealedChildren: Set[Symbol] = if (!isSealed) Set.empty else children /** Recursively assemble all children of this symbol. */ - def sealedDescendants: Set[Symbol] = children.flatMap(_.sealedDescendants) + this + final def sealedDescendants: Set[Symbol] = if (!isSealed) Set(this) else children.flatMap(_.sealedDescendants) + this @inline final def orElse(alt: => Symbol): Symbol = if (this ne NoSymbol) this else alt @inline final def andAlso(f: Symbol => Unit): Symbol = { if (this ne NoSymbol) f(this) ; this } @@ -2567,7 +2539,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** String representation of symbol's definition key word */ final def keyString: String = if (isJavaInterface) "interface" - else if (isTrait && !isImplClass) "trait" + else if (isTrait) "trait" else if (isClass) "class" else if (isType && !isParameter) "type" else if (isVariable) "var" @@ -2579,31 +2551,34 @@ trait Symbols extends api.Symbols { self: SymbolTable => private def symbolKind: SymbolKind = { var kind = - if (isTermMacro) ("term macro", "macro method", "MACM") - else if (isInstanceOf[FreeTermSymbol]) ("free term", "free term", "FTE") - else if (isInstanceOf[FreeTypeSymbol]) ("free type", "free type", "FTY") - else if (isPackageClass) ("package class", "package", "PKC") - else if (hasPackageFlag) ("package", "package", "PK") - else if (isPackageObject) ("package object", "package", "PKO") - else if (isPackageObjectClass) ("package object class", "package", "PKOC") - else if (isAnonymousClass) ("anonymous class", "anonymous class", "AC") - else if (isRefinementClass) ("refinement class", "", "RC") - else if (isModule) ("module", "object", "MOD") - else if (isModuleClass) ("module class", "object", "MODC") - else if (isGetter) ("getter", if (isSourceMethod) "method" else "value", "GET") - else if (isSetter) ("setter", if (isSourceMethod) "method" else "value", "SET") - else if (isTerm && isLazy) ("lazy value", "lazy value", "LAZ") - else if (isVariable) ("field", "variable", "VAR") - else if (isImplClass) ("implementation class", "class", "IMPL") - else if (isTrait) ("trait", "trait", "TRT") - else if (isClass) ("class", "class", "CLS") - else if (isType) ("type", "type", "TPE") - else if (isClassConstructor && (owner.hasCompleteInfo && isPrimaryConstructor)) ("primary constructor", "constructor", "PCTOR") - else if (isClassConstructor) ("constructor", "constructor", "CTOR") - else if (isSourceMethod) ("method", "method", "METH") - else if (isTerm) ("value", "value", "VAL") - else ("", "", "???") + if (isTermMacro) ("term macro", "macro method", "MACM") + else if (isInstanceOf[FreeTermSymbol]) ("free term", "free term", "FTE") + else if (isInstanceOf[FreeTypeSymbol]) ("free type", "free type", "FTY") + else if (isPackageClass) ("package class", "package", "PKC") + else if (hasPackageFlag) ("package", "package", "PK") + else if (isPackageObject) ("package object", "package", "PKO") + else if (isPackageObjectClass) ("package object class", "package", "PKOC") + else if (isAnonymousClass) ("anonymous class", "anonymous class", "AC") + else if (isRefinementClass) ("refinement class", "", "RC") + else if (isModule) ("module", "object", "MOD") + else if (isModuleClass) ("module class", "object", "MODC") + else if (isAccessor && + !hasFlag(STABLE | LAZY)) ("setter", "variable", "SET") + else if (isAccessor && !hasFlag(LAZY)) ("getter", "value", "GET") + else if (isTerm && hasFlag(LAZY)) ("lazy value", "lazy value", "LAZ") + else if (isVariable) ("field", "variable", "VAR") + else if (isTrait) ("trait", "trait", "TRT") + else if (isClass) ("class", "class", "CLS") + else if (isType) ("type", "type", "TPE") + else if (isClassConstructor && (owner.hasCompleteInfo && + isPrimaryConstructor)) ("primary constructor", "constructor", "PCTOR") + else if (isClassConstructor) ("constructor", "constructor", "CTOR") + else if (isMethod) ("method", "method", "METH") + else if (isTerm) ("value", "value", "VAL") + else ("", "", "???") + if (isSkolem) kind = (kind._1, kind._2, kind._3 + "#SKO") + SymbolKind(kind._1, kind._2, kind._3) } @@ -2671,12 +2646,17 @@ trait Symbols extends api.Symbols { self: SymbolTable => * If hasMeaninglessName is true, uses the owner's name to disambiguate identity. */ override def toString: String = { - if (isPackageObjectOrClass && !settings.debug) - s"package object ${owner.decodedName}" - else compose( - kindString, - if (hasMeaninglessName) owner.decodedName + idString else nameString - ) + val simplifyNames = !settings.debug + if (isPackageObjectOrClass && simplifyNames) s"package object ${owner.decodedName}" + else { + val kind = kindString + val _name: String = + if (hasMeaninglessName) owner.decodedName + idString + else if (simplifyNames && (kind == "variable" || kind == "value")) unexpandedName.getterName.decode.toString // TODO: make condition less gross? + else nameString + + compose(kind, _name) + } } /** String representation of location. @@ -2812,18 +2792,21 @@ trait Symbols extends api.Symbols { self: SymbolTable => ) ***/ override def isValueParameter = this hasFlag PARAM - override def isSetterParameter = isValueParameter && owner.isSetter - override def isAccessor = this hasFlag ACCESSOR - override def isGetter = isAccessor && !isSetter + override def isDefaultGetter = name containsName nme.DEFAULT_GETTER_STRING - override def isSetter = isAccessor && nme.isSetterName(name) // todo: make independent of name, as this can be forged. + + override def isAccessor = this hasFlag ACCESSOR + override def isGetter = isAccessor && !nme.isSetterName(name) // TODO: make independent of name, as this can be forged. + override def isSetter = isAccessor && nme.isSetterName(name) // TODO: make independent of name, as this can be forged. + override def isLocalDummy = nme.isLocalDummyName(name) + override def isClassConstructor = name == nme.CONSTRUCTOR override def isMixinConstructor = name == nme.MIXIN_CONSTRUCTOR - override def isConstructor = nme.isConstructorName(name) + override def isConstructor = isClassConstructor || isMixinConstructor - override def isPackageObject = isModule && (name == nme.PACKAGE) + override def isPackageObject = isModule && (name == nme.PACKAGE) // The name in comments is what it is being disambiguated from. // TODO - rescue CAPTURED from BYNAMEPARAM so we can see all the names. @@ -2831,7 +2814,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => case DEFAULTPARAM => "<defaultparam>" // TRAIT case MIXEDIN => "<mixedin>" // EXISTENTIAL case LABEL => "<label>" // CONTRAVARIANT / INCONSTRUCTOR - case PRESUPER => "<presuper>" // IMPLCLASS case BYNAMEPARAM => if (this.isValueParameter) "<bynameparam>" else "<captured>" // COVARIANT case _ => super.resolveOverloadedFlag(flag) } @@ -2876,17 +2858,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => this } - def setLazyAccessor(sym: Symbol): TermSymbol = { - assert(isLazy && (referenced == NoSymbol || referenced == sym), (this, debugFlagString, referenced, sym)) - referenced = sym - this - } - - override def lazyAccessor: Symbol = { - assert(isLazy, this) - referenced - } - /** change name by appending $$<fully-qualified-name-of-class `base`> * Do the same for any accessed symbols or setters/getters */ @@ -2915,12 +2886,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def associatedFile_=(f: AbstractFile) { moduleClass.associatedFile = f } override def moduleClass = referenced - override def companionClass = - flatOwnerInfo.decl(name.toTypeName).suchThat(sym => sym.isClass && (sym isCoDefinedWith this)) override def owner = { if (Statistics.hotEnabled) Statistics.incCounter(ownerCount) - // a module symbol may have the lateMETHOD flag after refchecks, see isModuleNotMethod + // a non-static module symbol gets the METHOD flag in uncurry's info transform -- see isModuleNotMethod if (!isMethod && needsFlatClasses) rawowner.owner else rawowner } @@ -2940,38 +2909,23 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** A class for method symbols */ class MethodSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName) extends TermSymbol(initOwner, initPos, initName) with MethodSymbolApi { - private[this] var mtpePeriod = NoPeriod - private[this] var mtpePre: Type = _ - private[this] var mtpeResult: Type = _ - private[this] var mtpeInfo: Type = _ - override def isLabel = this hasFlag LABEL override def isVarargsMethod = this hasFlag VARARGS override def isLiftedMethod = this hasFlag LIFTED - // TODO - this seems a strange definition for "isSourceMethod", given that - // it does not make any specific effort to exclude synthetics. Figure out what - // this method is really for and what logic makes sense. - override def isSourceMethod = !(this hasFlag STABLE) // exclude all accessors + // TODO: this definition of isSourceMethod makes no sense -- inline it and re-evaluate at each call site. + // I'm guessing it meant "method written by user, and not generated by the compiler" + // (And then assuming those generated by the compiler don't require certain transformations?) + // Use SYNTHETIC/ARTIFACT instead as an indicator? I don't see how it makes sense to only exclude getters. + // Note also that trait vals are modelled as getters, and thus that user-supplied code appears in their rhs. + // Originally, it may have been an optimization to skip methods that were not user-defined (getters), + // but it doesn't even exclude setters, contrary to its original comment (// exclude all accessors) + override def isSourceMethod = !(this hasFlag STABLE) + // unfortunately having the CASEACCESSOR flag does not actually mean you // are a case accessor (you can also be a field.) override def isCaseAccessorMethod = isCaseAccessor - def typeAsMemberOf(pre: Type): Type = { - if (mtpePeriod == currentPeriod) { - if ((mtpePre eq pre) && (mtpeInfo eq info)) return mtpeResult - } else if (isValid(mtpePeriod)) { - mtpePeriod = currentPeriod - if ((mtpePre eq pre) && (mtpeInfo eq info)) return mtpeResult - } - val res = pre.computeMemberType(this) - mtpePeriod = currentPeriod - mtpePre = pre - mtpeInfo = info - mtpeResult = res - res - } - override def isVarargs: Boolean = definitions.isVarArgsList(paramss.flatten) override def returnType: Type = { @@ -2985,7 +2939,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => loop(info) } - override def exceptions = annotations flatMap ThrownException.unapply + override def exceptions = for (ThrownException(tp) <- annotations) yield tp.typeSymbol } implicit val MethodSymbolTag = ClassTag[MethodSymbol](classOf[MethodSymbol]) @@ -3232,7 +3186,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def resolveOverloadedFlag(flag: Long) = flag match { case INCONSTRUCTOR => "<inconstructor>" // INCONSTRUCTOR / CONTRAVARIANT / LABEL case EXISTENTIAL => "<existential>" // EXISTENTIAL / MIXEDIN - case IMPLCLASS => "<implclass>" // IMPLCLASS / PRESUPER case _ => super.resolveOverloadedFlag(flag) } @@ -3244,7 +3197,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def isAbstractClass = this hasFlag ABSTRACT override def isCaseClass = this hasFlag CASE override def isClassLocalToConstructor = this hasFlag INCONSTRUCTOR - override def isImplClass = this hasFlag IMPLCLASS override def isModuleClass = this hasFlag MODULE override def isPackageClass = this hasFlag PACKAGE override def isTrait = this hasFlag TRAIT @@ -3262,13 +3214,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => // The corresponding interface is the last parent by convention. private def lastParent = if (tpe.parents.isEmpty) NoSymbol else tpe.parents.last.typeSymbol - override def toInterface: Symbol = ( - if (isImplClass) { - if (phase.next.erasedTypes) lastParent - else owner.info.decl(tpnme.interfaceName(name)) - } - else super.toInterface - ) /** Is this class locally defined? * A class is local, if @@ -3289,7 +3234,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => * returned, otherwise, `NoSymbol` is returned. */ protected final def companionModule0: Symbol = - flatOwnerInfo.decl(name.toTermName).suchThat(sym => sym.isModuleNotMethod && (sym isCoDefinedWith this)) + flatOwnerInfo.decl(name.toTermName).suchThat(sym => sym.isModule && (sym isCoDefinedWith this)) override def companionModule = companionModule0 override def companionSymbol = companionModule0 @@ -3299,7 +3244,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def existentialBound = GenPolyType(this.typeParams, TypeBounds.upper(this.classBound)) - def primaryConstructorName = if (this hasFlag TRAIT | IMPLCLASS) nme.MIXIN_CONSTRUCTOR else nme.CONSTRUCTOR + def primaryConstructorName = if (this hasFlag TRAIT) nme.MIXIN_CONSTRUCTOR else nme.CONSTRUCTOR override def primaryConstructor = { val c = info decl primaryConstructorName @@ -3429,13 +3374,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => def implicitMembers: Scope = { val tp = info if ((implicitMembersCacheKey1 ne tp) || (implicitMembersCacheKey2 ne tp.decls.elems)) { - // Skip a package object class, because the members are also in - // the package and we wish to avoid spurious ambiguities as in pos/t3999. - if (!isPackageObjectClass) { - implicitMembersCacheValue = tp.implicitMembers - implicitMembersCacheKey1 = tp - implicitMembersCacheKey2 = tp.decls.elems - } + implicitMembersCacheValue = tp.membersBasedOnFlags(BridgeFlags, IMPLICIT) + implicitMembersCacheKey1 = tp + implicitMembersCacheKey2 = tp.decls.elems } implicitMembersCacheValue } @@ -3454,12 +3395,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => } } - trait ImplClassSymbol extends ClassSymbol { - override def sourceModule = companionModule - // override def isImplClass = true - override def typeOfThis = thisSym.tpe // don't use the ModuleClassSymbol typeOfThisCache. - } - class PackageClassSymbol protected[Symbols] (owner0: Symbol, pos0: Position, name0: TypeName) extends ModuleClassSymbol(owner0, pos0, name0) { override def sourceModule = companionModule @@ -3471,7 +3406,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => extends ClassSymbol(owner0, pos0, tpnme.REFINE_CLASS_NAME) { override def name_=(name: Name) { abort("Cannot set name of RefinementClassSymbol to " + name) - super.name_=(name) } override def isRefinementClass = true override def isAnonOrRefinementClass = true @@ -3520,7 +3454,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def companionSymbol = fail(NoSymbol) } class StubClassSymbol(owner0: Symbol, name0: TypeName, val missingMessage: String) extends ClassSymbol(owner0, owner0.pos, name0) with StubSymbol - class StubPackageClassSymbol(owner0: Symbol, name0: TypeName, val missingMessage: String) extends PackageClassSymbol(owner0, owner0.pos, name0) with StubSymbol class StubTermSymbol(owner0: Symbol, name0: TermName, val missingMessage: String) extends TermSymbol(owner0, owner0.pos, name0) with StubSymbol trait FreeSymbol extends Symbol { @@ -3718,7 +3651,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => assert((prev eq null) || phaseId(validFrom) > phaseId(prev.validFrom), this) assert(validFrom != NoPeriod, this) - private def phaseString = "%s: %s".format(phaseOf(validFrom), info) + private def phaseString = { + val phase = phaseOf(validFrom) + s"$phase: ${exitingPhase(phase)(info.toString)}" + } override def toString = toList reverseMap (_.phaseString) mkString ", " def toList: List[TypeHistory] = this :: ( if (prev eq null) Nil else prev.toList ) @@ -3749,9 +3685,15 @@ trait Symbols extends api.Symbols { self: SymbolTable => val AllOps = SymbolOps(isFlagRelated = false, mask = 0L) def FlagOps(mask: Long) = SymbolOps(isFlagRelated = true, mask = mask) - private def relevantSymbols(syms: Seq[Symbol]) = syms.flatMap(sym => List(sym, sym.moduleClass, sym.sourceModule)) - def markFlagsCompleted(syms: Symbol*)(mask: Long): Unit = relevantSymbols(syms).foreach(_.markFlagsCompleted(mask)) - def markAllCompleted(syms: Symbol*): Unit = relevantSymbols(syms).foreach(_.markAllCompleted) + private def forEachRelevantSymbols(syms: Seq[Symbol], fn: Symbol => Unit): Unit = + syms.foreach { sym => + fn(sym) + fn(sym.moduleClass) + fn(sym.sourceModule) + } + + def markFlagsCompleted(syms: Symbol*)(mask: Long): Unit = forEachRelevantSymbols(syms, _.markFlagsCompleted(mask)) + def markAllCompleted(syms: Symbol*): Unit = forEachRelevantSymbols(syms, _.markAllCompleted) } object SymbolsStats { |