summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Namers.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Namers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala72
1 files changed, 34 insertions, 38 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 4ad81b60ae..8943ec810d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -7,7 +7,6 @@ package scala.tools.nsc
package typechecker
import scala.collection.mutable
-import scala.annotation.tailrec
import symtab.Flags._
import scala.language.postfixOps
import scala.reflect.internal.util.ListOfNil
@@ -115,21 +114,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 noEnterGetterSetter(vd: ValDef) = !vd.mods.isLazy && (
- !owner.isClass
- || (vd.mods.isPrivateLocal && !vd.mods.isCaseAccessor)
- || (vd.name startsWith nme.OUTER)
- || (context.unit.isJava)
- || isEnumConstant(vd)
- )
- def noFinishGetterSetter(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:
@@ -170,13 +162,9 @@ trait Namers extends MethodSynthesis {
def updatePosFlags(sym: Symbol, pos: Position, flags: Long): Symbol = {
debuglog("[overwrite] " + sym)
val newFlags = (sym.flags & LOCKED) | flags
- sym.rawInfo match {
- case tr: TypeRef =>
- // !!! needed for: pos/t5954d; the uniques type cache will happily serve up the same TypeRef
- // over this mutated symbol, and we witness a stale cache for `parents`.
- tr.invalidateCaches()
- case _ =>
- }
+ // !!! needed for: pos/t5954d; the uniques type cache will happily serve up the same TypeRef
+ // over this mutated symbol, and we witness a stale cache for `parents`.
+ invalidateCaches(sym.rawInfo, sym :: sym.moduleClass :: Nil)
sym reset NoType setFlag newFlags setPos pos
sym.moduleClass andAlso (updatePosFlags(_, pos, moduleClassFlags(flags)))
@@ -655,14 +643,20 @@ trait Namers extends MethodSynthesis {
}
}
- def enterValDef(tree: ValDef) {
- if (noEnterGetterSetter(tree))
- assignAndEnterFinishedSymbol(tree)
- else
- 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 (isEnumConstant(tree))
+ if (isScala && deriveAccessors(tree)) enterGetterSetter(tree)
+ else assignAndEnterFinishedSymbol(tree)
+
+ if (isEnumConstant(tree)) {
tree.symbol setInfo ConstantType(Constant(tree.symbol))
+ tree.symbol.owner.linkedClassOfClass addChild tree.symbol
+ }
}
def enterLazyVal(tree: ValDef, lazyAccessor: Symbol): TermSymbol = {
@@ -1600,11 +1594,7 @@ trait Namers extends MethodSynthesis {
import SymValidateErrors._
def fail(kind: SymValidateErrors.Value) = SymbolValidationError(sym, kind)
- def checkWithDeferred(flag: Int) {
- if (sym hasFlag flag)
- AbstractMemberWithModiferError(sym, flag)
- }
- def checkNoConflict(flag1: Int, flag2: Int) {
+ def checkNoConflict(flag1: Int, flag2: Int) = {
if (sym hasAllFlags flag1.toLong | flag2)
IllegalModifierCombination(sym, flag1, flag2)
}
@@ -1643,6 +1633,10 @@ trait Namers extends MethodSynthesis {
checkNoConflict(ABSTRACT, FINAL)
if (sym.isDeferred) {
+ def checkWithDeferred(flag: Int) = {
+ if (sym hasFlag flag)
+ AbstractMemberWithModiferError(sym, flag)
+ }
// Is this symbol type always allowed the deferred flag?
def symbolAllowsDeferred = (
sym.isValueParameter
@@ -1658,14 +1652,16 @@ trait Namers extends MethodSynthesis {
)
if (sym hasAnnotation NativeAttr)
sym resetFlag DEFERRED
- else if (!symbolAllowsDeferred && ownerRequiresConcrete)
- fail(AbstractVar)
+ else {
+ if (!symbolAllowsDeferred && ownerRequiresConcrete) fail(AbstractVar)
- checkWithDeferred(PRIVATE)
- checkWithDeferred(FINAL)
+ checkWithDeferred(PRIVATE)
+ checkWithDeferred(FINAL)
+ }
}
- checkNoConflict(FINAL, SEALED)
+ if (!sym.isJavaEnum)
+ checkNoConflict(FINAL, SEALED)
checkNoConflict(PRIVATE, PROTECTED)
// checkNoConflict(PRIVATE, OVERRIDE) // this one leads to bad error messages like #4174, so catch in refchecks
// checkNoConflict(PRIVATE, FINAL) // can't do this because FINAL also means compile-time constant