From cc70cfb5024729935b5dd9be385847bd43c90b04 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Mon, 24 Aug 2015 18:47:31 -0700 Subject: Simplify decision whether to derive accessors Originally (modulo renaming & reduction of double negation in previous commit): ``` def deriveAccessors(vd: ValDef) = vd.mods.isLazy || !( !owner.isClass || (vd.mods.isPrivateLocal && !vd.mods.isCaseAccessor) // this is an error -- now checking first || (vd.name startsWith nme.OUTER) || (context.unit.isJava) // pulled out to caller || isEnumConstant(vd) ) def deriveAccessorTrees(vd: ValDef) = !( (vd.mods.isPrivateLocal && !vd.mods.isLazy) // lazy was pulled out to outer disjunction || vd.symbol.isModuleVar // pulled out to caller || isEnumConstant(vd)) ``` With changes in comments above, these conditions are now captured by one method. --- .../tools/nsc/typechecker/ContextErrors.scala | 2 +- .../tools/nsc/typechecker/MethodSynthesis.scala | 13 +++------ .../scala/tools/nsc/typechecker/Namers.scala | 31 +++++++++++----------- 3 files changed, 19 insertions(+), 27 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index b0bd9977a8..1b2e7f628e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -1105,7 +1105,7 @@ trait ContextErrors { def GetterDefinedTwiceError(getter: Symbol) = issueSymbolTypeError(getter, getter+" is defined twice") - def ValOrValWithSetterSuffixError(tree: Tree) = + def ValOrVarWithSetterSuffixError(tree: Tree) = issueNormalTypeError(tree, "Names of vals or vars may not end in `_='") def PrivateThisCaseClassParameterError(tree: Tree) = diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index 5f5e13951d..5fdddf0641 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -135,18 +135,12 @@ trait MethodSynthesis { } // TODO: see if we can link symbol creation & tree derivation by sharing the Field/Getter/Setter factories - def enterGetterSetter(tree: ValDef) { - val ValDef(mods, name, _, _) = tree - if (nme.isSetterName(name)) - ValOrValWithSetterSuffixError(tree) - + def enterGetterSetter(tree: ValDef): Unit = { tree.symbol = - if (mods.isLazy) { + if (tree.mods.isLazy) { val lazyValGetter = LazyValGetter(tree).createAndEnterSymbol() enterLazyVal(tree, lazyValGetter) } else { - if (mods.isPrivateLocal) - PrivateThisCaseClassParameterError(tree) val getter = Getter(tree) val getterSym = getter.createAndEnterSymbol() @@ -163,7 +157,6 @@ trait MethodSynthesis { else enterStrictVal(tree) } - enterBeans(tree) } @@ -184,7 +177,7 @@ trait MethodSynthesis { } def addDerivedTrees(typer: Typer, stat: Tree): List[Tree] = stat match { - case vd @ ValDef(mods, name, tpt, rhs) if deriveAccessorTrees(vd) => + case vd @ ValDef(mods, name, tpt, rhs) if deriveAccessors(vd) && !vd.symbol.isModuleVar => // If we don't save the annotations, they seem to wander off. val annotations = stat.symbol.initialize.annotations val trees = ( diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index f54b330284..254cb7111c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -115,21 +115,14 @@ trait Namers extends MethodSynthesis { TypeSigError(tree, ex) alt } - // PRIVATE | LOCAL are fields generated for primary constructor arguments - // @PP: ...or fields declared as private[this]. PARAMACCESSOR marks constructor arguments. - // Neither gets accessors so the code is as far as I know still correct. - def deriveAccessors(vd: ValDef) = vd.mods.isLazy || !( - !owner.isClass - || (vd.mods.isPrivateLocal && !vd.mods.isCaseAccessor) - || (vd.name startsWith nme.OUTER) - || (context.unit.isJava) - || isEnumConstant(vd) - ) - def deriveAccessorTrees(vd: ValDef) = !( - (vd.mods.isPrivateLocal && !vd.mods.isLazy) // all lazy vals need accessors, even private[this] - || vd.symbol.isModuleVar - || isEnumConstant(vd)) + // All lazy vals need accessors, including those owned by terms (e.g., in method) or private[this] in a class + def deriveAccessors(vd: ValDef) = vd.mods.isLazy || (owner.isClass && deriveAccessorsInClass(vd)) + + private def deriveAccessorsInClass(vd: ValDef) = + !vd.mods.isPrivateLocal && // note, private[this] lazy vals do get accessors -- see outer disjunction of deriveAccessors + !(vd.name startsWith nme.OUTER) && // outer accessors are added later, in explicitouter + !isEnumConstant(vd) // enums can only occur in classes, so only check here /** Determines whether this field holds an enum constant. * To qualify, the following conditions must be met: @@ -655,8 +648,14 @@ trait Namers extends MethodSynthesis { } } - def enterValDef(tree: ValDef) { - if (deriveAccessors(tree)) enterGetterSetter(tree) + def enterValDef(tree: ValDef): Unit = { + val isScala = !context.unit.isJava + if (isScala) { + if (nme.isSetterName(tree.name)) ValOrVarWithSetterSuffixError(tree) + if (tree.mods.isPrivateLocal && tree.mods.isCaseAccessor) PrivateThisCaseClassParameterError(tree) + } + + if (isScala && deriveAccessors(tree)) enterGetterSetter(tree) else assignAndEnterFinishedSymbol(tree) if (isEnumConstant(tree)) -- cgit v1.2.3