diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-09-27 11:43:07 -0700 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-09-27 11:43:07 -0700 |
commit | 8ae942f7c2700aed85a481a40a8abd4fac783587 (patch) | |
tree | 2fa31382a2d27704280b62cfe2c5f952d4fd7e41 | |
parent | 71212e51ed5990a3f42e50edea0cebeac3b0d4ca (diff) | |
parent | 693ecffbaf5be036e05300a1ee3a8444c0ac0fe3 (diff) | |
download | scala-8ae942f7c2700aed85a481a40a8abd4fac783587.tar.gz scala-8ae942f7c2700aed85a481a40a8abd4fac783587.tar.bz2 scala-8ae942f7c2700aed85a481a40a8abd4fac783587.zip |
Merge pull request #2995 from paulp/pr/defaultparam
Fix up DEFAULTPARAM semantics.
6 files changed, 15 insertions, 14 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 347426d42a..4cfac91a94 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -1272,9 +1272,7 @@ trait Namers extends MethodSynthesis { val defRhs = copyUntyped(vparam.rhs) val defaultTree = atPos(vparam.pos.focus) { - DefDef( - Modifiers(meth.flags & DefaultGetterFlags) | (SYNTHETIC | DEFAULTPARAM | oflag).toLong, - name, deftParams, defvParamss, defTpt, defRhs) + DefDef(Modifiers(paramFlagsToDefaultGetter(meth.flags)) | oflag, name, deftParams, defvParamss, defTpt, defRhs) } if (!isConstr) methOwner.resetFlag(INTERFACE) // there's a concrete member now diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index d921868f31..f3aed66bc5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -127,14 +127,14 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans // those with the DEFAULTPARAM flag, and infer the methods. Looking for the methods // directly requires inspecting the parameter list of every one. That modification // shaved 95% off the time spent in this method. - val defaultGetters = defaultClass.info.findMembers(0L, DEFAULTPARAM) + val defaultGetters = defaultClass.info.findMembers(excludedFlags = PARAM, requiredFlags = DEFAULTPARAM) val defaultMethodNames = defaultGetters map (sym => nme.defaultGetterToMethod(sym.name)) defaultMethodNames.toList.distinct foreach { name => - val methods = clazz.info.findMember(name, 0L, METHOD, stableOnly = false).alternatives + val methods = clazz.info.findMember(name, 0L, requiredFlags = METHOD, stableOnly = false).alternatives def hasDefaultParam(tpe: Type): Boolean = tpe match { case MethodType(params, restpe) => (params exists (_.hasDefault)) || hasDefaultParam(restpe) - case _ => false + case _ => false } val haveDefaults = methods filter (sym => hasDefaultParam(sym.info) && !nme.isProtectedAccessorName(sym.name)) diff --git a/src/reflect/scala/reflect/internal/Flags.scala b/src/reflect/scala/reflect/internal/Flags.scala index c286ea53c6..dcdf6728ce 100644 --- a/src/reflect/scala/reflect/internal/Flags.scala +++ b/src/reflect/scala/reflect/internal/Flags.scala @@ -279,11 +279,13 @@ class Flags extends ModifierFlags { final val GetterFlags = ~(PRESUPER | MUTABLE) final val SetterFlags = ~(PRESUPER | MUTABLE | STABLE | CASEACCESSOR | IMPLICIT) - /** When a symbol for a default getter is created, it inherits these - * flags from the method with the default. Other flags applied at creation - * time are SYNTHETIC, DEFAULTPARAM, and possibly OVERRIDE, and maybe PRESUPER. + /** Since DEFAULTPARAM is overloaded with TRAIT, we need some additional + * means of determining what that bit means. Usually DEFAULTPARAM is coupled + * with PARAM, which suffices. Default getters get METHOD instead. + * This constant is the mask of flags which can survive from the parameter modifiers. + * See paramFlagsToDefaultGetter for the full logic. */ - final val DefaultGetterFlags = PRIVATE | PROTECTED | FINAL + final val DefaultGetterFlags = PRIVATE | PROTECTED | FINAL | PARAMACCESSOR /** When a symbol for a method parameter is created, only these flags survive * from Modifiers. Others which may be applied at creation time are: @@ -321,6 +323,9 @@ class Flags extends ModifierFlags { */ final val TopLevelPickledFlags = PickledFlags & ~(MODULE | METHOD | PACKAGE | PARAM | EXISTENTIAL) + def paramFlagsToDefaultGetter(paramFlags: Long): Long = + (paramFlags & DefaultGetterFlags) | SYNTHETIC | METHOD | DEFAULTPARAM + def getterFlags(fieldFlags: Long): Long = ACCESSOR + ( if ((fieldFlags & MUTABLE) != 0) fieldFlags & ~MUTABLE & ~PRESUPER else fieldFlags & ~PRESUPER | STABLE diff --git a/src/reflect/scala/reflect/internal/HasFlags.scala b/src/reflect/scala/reflect/internal/HasFlags.scala index 292b784c0c..4e12998ac7 100644 --- a/src/reflect/scala/reflect/internal/HasFlags.scala +++ b/src/reflect/scala/reflect/internal/HasFlags.scala @@ -81,7 +81,7 @@ trait HasFlags { // identically, testing for a single flag. def hasAbstractFlag = hasFlag(ABSTRACT) def hasAccessorFlag = hasFlag(ACCESSOR) - def hasDefault = hasAllFlags(DEFAULTPARAM | PARAM) + def hasDefault = hasFlag(DEFAULTPARAM) && hasFlag(METHOD | PARAM) // Second condition disambiguates with TRAIT def hasLocalFlag = hasFlag(LOCAL) def hasModuleFlag = hasFlag(MODULE) def hasPackageFlag = hasFlag(PACKAGE) diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index d58ea09386..14d742fc2c 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -571,7 +571,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => def isValue = false def isValueParameter = false def isVariable = false - override def hasDefault = false def isTermMacro = false /** Qualities of MethodSymbols, always false for TypeSymbols @@ -2601,7 +2600,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def companionSymbol: Symbol = companionClass override def moduleClass = if (isModule) referenced else NoSymbol - override def hasDefault = this hasFlag DEFAULTPARAM // overloaded with TRAIT override def isBridge = this hasFlag BRIDGE override def isEarlyInitialized = this hasFlag PRESUPER override def isMethod = this hasFlag METHOD diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala index c8ae4df13d..9be1768289 100644 --- a/src/reflect/scala/reflect/internal/TreeGen.scala +++ b/src/reflect/scala/reflect/internal/TreeGen.scala @@ -376,7 +376,7 @@ abstract class TreeGen extends macros.TreeBuilder { DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(Constant()))))) } } - constr foreach (ensureNonOverlapping(_, parents ::: gvdefs, focus=false)) + constr foreach (ensureNonOverlapping(_, parents ::: gvdefs, focus = false)) // Field definitions for the class - remove defaults. val fieldDefs = vparamss.flatten map (vd => copyValDef(vd)(mods = vd.mods &~ DEFAULTPARAM, rhs = EmptyTree)) |