summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2007-02-01 17:57:01 +0000
committerMartin Odersky <odersky@gmail.com>2007-02-01 17:57:01 +0000
commit29f933b60ace6dbbeb45e0b31b0ed6d724dc74e9 (patch)
treef2c11c08576c4f0f387c1a0a7d6ad425270cd23c /src
parent039e9821820695dc90ea712126a4de22e3a23341 (diff)
downloadscala-29f933b60ace6dbbeb45e0b31b0ed6d724dc74e9.tar.gz
scala-29f933b60ace6dbbeb45e0b31b0ed6d724dc74e9.tar.bz2
scala-29f933b60ace6dbbeb45e0b31b0ed6d724dc74e9.zip
added private[this] and protected[this] modifiers.
added modifiers for primary constructors.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala37
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala134
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Flags.scala10
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala5
-rw-r--r--src/compiler/scala/tools/nsc/transform/OverridingPairs.scala5
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala55
11 files changed, 148 insertions, 117 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 9de909d08c..694383abe9 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -17,7 +17,7 @@ trait Trees requires Global {
//statistics
var nodeCount = 0
- case class Modifiers(flags: int, privateWithin: Name) {
+ case class Modifiers(flags: int, privateWithin: Name, attributes: List[Attribute]) {
def isCovariant = hasFlag(COVARIANT )
def isContravariant = hasFlag(CONTRAVARIANT)
def isPrivate = hasFlag(PRIVATE )
@@ -38,22 +38,24 @@ trait Trees requires Global {
def & (flag: Int): Modifiers = {
val flags1 = flags & flag
if (flags1 == flags) this
- else Modifiers(flags1, privateWithin) setAttr attributes
+ else Modifiers(flags1, privateWithin, attributes)
}
def &~ (flag: Int): Modifiers = {
val flags1 = flags & (~flag)
if (flags1 == flags) this
- else Modifiers(flags1, privateWithin) setAttr attributes
+ else Modifiers(flags1, privateWithin, attributes)
}
def | (flag: int): Modifiers = {
val flags1 = flags | flag
if (flags1 == flags) this
- else Modifiers(flags1, privateWithin) setAttr attributes
+ else Modifiers(flags1, privateWithin, attributes)
}
- def setAttr(attrs: List[Attribute]): this.type = {attributes = attrs; this }
- var attributes: List[Attribute] = List()
+ def withAttributes(attrs: List[Attribute]) =
+ if (attrs.isEmpty) this
+ else Modifiers(flags, privateWithin, attributes ::: attrs)
}
+ def Modifiers(flags: int, privateWithin: Name): Modifiers = Modifiers(flags, privateWithin, List())
def Modifiers(flags: int): Modifiers = Modifiers(flags, nme.EMPTY.toTypeName)
def Modifiers(flags: long): Modifiers = Modifiers(flags.asInstanceOf[int])
@@ -248,8 +250,8 @@ trait Trees requires Global {
* and value parameter fields.
* @return ...
*/
- def ClassDef(sym: Symbol, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree]): ClassDef =
- ClassDef(sym, Template(sym.info.parents map TypeTree, vparamss, argss, body))
+ def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree]): ClassDef =
+ ClassDef(sym, Template(sym.info.parents map TypeTree, constrMods, vparamss, argss, body))
/** Singleton object definition
*
@@ -312,7 +314,7 @@ trait Trees requires Global {
assert(rhs.isTerm)
}
- def DefDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef =
+ def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef =
posAssigner.atPos(sym.pos) {
assert(sym != NoSymbol)
DefDef(Modifiers(sym.flags),
@@ -323,11 +325,17 @@ trait Trees requires Global {
rhs) setSymbol sym
}
- def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef = {
+ def DefDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef =
+ DefDef(sym, Modifiers(sym.flags), vparamss, rhs)
+
+ def DefDef(sym: Symbol, mods: Modifiers, rhs: List[List[Symbol]] => Tree): DefDef = {
val vparamss = syntheticParams(sym, sym.tpe)
- DefDef(sym, vparamss map (.map(ValDef)), rhs(vparamss))
+ DefDef(sym, mods, vparamss map (.map(ValDef)), rhs(vparamss))
}
+ def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef =
+ DefDef(sym, Modifiers(sym.flags), rhs)
+
/** Abstract type or type parameter
*
* @param mods
@@ -430,11 +438,11 @@ trait Trees requires Global {
* @param body ...
* @return ...
*/
- def Template(parents: List[Tree], vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree]): Template = {
+ def Template(parents: List[Tree], constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree]): Template = {
/** Add constructor to template */
var vparamss1 =
vparamss map (.map (vd => {
- val ret = ValDef(Modifiers(vd.mods.flags & IMPLICIT | PARAM) setAttr vd.mods.attributes,
+ val ret = ValDef(Modifiers(vd.mods.flags & IMPLICIT | PARAM) withAttributes vd.mods.attributes,
vd.name, vd.tpt.duplicate, EmptyTree).setPos(vd.pos)
if (false/*inIDE*/ && vd.symbol != NoSymbol)
ret.symbol = vd.symbol
@@ -445,7 +453,8 @@ trait Trees requires Global {
vparamss1 = List() :: vparamss1;
val superRef: Tree = Select(Super(nme.EMPTY.toTypeName, nme.EMPTY.toTypeName), nme.CONSTRUCTOR)
val superCall = posAssigner.atPos(parents.head.pos) { (superRef /: argss) (Apply) }
- val constr: Tree = DefDef(NoMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), superCall)
+ val constr: Tree =
+ DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), superCall)
Template(parents, List.flatten(vparamss) ::: constr :: body)
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index c9e5d94a0d..3290333d2d 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -1407,22 +1407,53 @@ trait Parsers requires SyntaxAnalyzer {
////////// MODIFIERS ////////////////////////////////////////////////////////////
+ private def normalize(mods: Modifiers): Modifiers =
+ if ((mods hasFlag Flags.PRIVATE) && mods.privateWithin != nme.EMPTY.toTypeName)
+ mods &~ Flags.PRIVATE
+ else if ((mods hasFlag Flags.ABSTRACT) && (mods hasFlag Flags.OVERRIDE))
+ mods &~ (Flags.ABSTRACT | Flags.OVERRIDE) | Flags.ABSOVERRIDE
+ else
+ mods
+
+ private def addMod(mods: Modifiers, mod: int): Modifiers = {
+ if (mods hasFlag mod) syntaxError(in.currentPos, "repeated modifier", false)
+ in.nextToken()
+ mods | mod
+ }
+
+ /** AccessQualifier ::= "[" Id | this "]"
+ */
+ def accessQualifierOpt(mods: Modifiers) = {
+ var result = mods
+ if (in.token == LBRACKET) {
+ in.nextToken()
+ if (mods.privateWithin != nme.EMPTY.toTypeName)
+ syntaxError("duplicate private/protected qualifier", false)
+ result = if (in.token == THIS) { in.nextToken(); mods | Flags.LOCAL }
+ else Modifiers(mods.flags, ident().toTypeName)
+ accept(RBRACKET)
+ }
+ result
+ }
+
+ /** AccessModifier ::= (private | protected) [AccessQualifier]
+ */
+ def accessModifierOpt(): Modifiers = normalize {
+ in.token match {
+ case PRIVATE => accessQualifierOpt(Modifiers(Flags.PRIVATE))
+ case PROTECTED => accessQualifierOpt(Modifiers(Flags.PROTECTED))
+ case _ => NoMods
+ }
+ }
+
/** Modifiers ::= {Modifier}
* Modifier ::= LocalModifier
+ * | AccessModifier
* | override
- * | (private | protected) [ "[" Id "]" ]
+ * | (private | protected) [ "[" Id | this "]" ]
*/
- def modifiers(): Modifiers = {
- var privateWithin: Name = nme.EMPTY.toTypeName
- def qualifierOpt: unit =
- if (in.token == LBRACKET) {
- in.nextToken()
- if (privateWithin != nme.EMPTY.toTypeName)
- syntaxError("duplicate private/protected qualifier", false)
- privateWithin = ident().toTypeName
- accept(RBRACKET)
- }
- def loop(mods: int): int = in.token match {
+ def modifiers(): Modifiers = normalize {
+ def loop(mods: Modifiers): Modifiers = in.token match {
case ABSTRACT =>
loop(addMod(mods, Flags.ABSTRACT))
case FINAL =>
@@ -1430,14 +1461,9 @@ trait Parsers requires SyntaxAnalyzer {
case SEALED =>
loop(addMod(mods, Flags.SEALED))
case PRIVATE =>
- var mods1 = addMod(mods, Flags.PRIVATE)
- qualifierOpt
- if (privateWithin != nme.EMPTY.toTypeName) mods1 = mods
- loop(mods1)
+ loop(accessQualifierOpt(addMod(mods, Flags.PRIVATE)))
case PROTECTED =>
- val mods1 = addMod(mods, Flags.PROTECTED)
- qualifierOpt
- loop(mods1)
+ loop(accessQualifierOpt(addMod(mods, Flags.PROTECTED)))
case OVERRIDE =>
loop(addMod(mods, Flags.OVERRIDE))
case IMPLICIT =>
@@ -1445,17 +1471,14 @@ trait Parsers requires SyntaxAnalyzer {
case _ =>
mods
}
- var mods = loop(0)
- if ((mods & (Flags.ABSTRACT | Flags.OVERRIDE)) == (Flags.ABSTRACT | Flags.OVERRIDE))
- mods = mods & ~(Flags.ABSTRACT | Flags.OVERRIDE) | Flags.ABSOVERRIDE
- Modifiers(mods, privateWithin)
+ loop(NoMods)
}
/** LocalModifiers ::= {LocalModifier}
* LocalModifier ::= abstract | final | sealed | implicit
*/
def localModifiers(): Modifiers = {
- def loop(mods: int): int = in.token match {
+ def loop(mods: Modifiers): Modifiers = in.token match {
case ABSTRACT =>
loop(addMod(mods, Flags.ABSTRACT))
case FINAL =>
@@ -1467,14 +1490,7 @@ trait Parsers requires SyntaxAnalyzer {
case _ =>
mods
}
- Modifiers(loop(0))
- }
-
- private def addMod(mods: int, mod: int): int = {
- if ((mods & mod) != 0)
- syntaxError(in.currentPos, "repeated modifier", false)
- in.nextToken()
- mods | mod
+ loop(NoMods)
}
//////// PARAMETERS //////////////////////////////////////////////////////////
@@ -1523,7 +1539,7 @@ trait Parsers requires SyntaxAnalyzer {
}
paramType()
}
- ValDef((mods | implicitmod | bynamemod) setAttr attrs, name, tpt, EmptyTree)
+ ValDef((mods | implicitmod | bynamemod) withAttributes attrs, name, tpt, EmptyTree)
}
}
def paramClause(): List[ValDef] = {
@@ -1899,7 +1915,7 @@ trait Parsers requires SyntaxAnalyzer {
/** TmplDef ::= [case] class ClassDef
* | [case] object ObjectDef
- * | trait MixinClassDef
+ * | trait TraitDef
*/
def tmplDef(mods: Modifiers): Tree = in.token match {
case TRAIT =>
@@ -1917,8 +1933,9 @@ trait Parsers requires SyntaxAnalyzer {
EmptyTree
}
- /** ClassDef ::= Id [TypeParamClause] ClassParamClauses RequiresTypeOpt ClassTemplate
- * MixinClassDef ::= Id [TypeParamClause] RequiresTypeOpt MixinClassTemplate
+ /** ClassDef ::= Id [TypeParamClause]
+ [AccessModifier] ClassParamClauses RequiresTypeOpt ClassTemplate
+ * TraitDef ::= Id [TypeParamClause] RequiresTypeOpt MixinClassTemplate
*/
def classDef(mods: Modifiers): ClassDef =
atPos(in.skipToken()) {
@@ -1928,11 +1945,14 @@ trait Parsers requires SyntaxAnalyzer {
val tparams = typeParamClauseOpt(name, implicitViewBuf)
implicitClassViews = implicitViewBuf.toList
//if (mods.hasFlag(Flags.CASE) && in.token != LPAREN) accept(LPAREN)
- val vparamss = if (mods.hasFlag(Flags.TRAIT)) List()
- else paramClauses(name, implicitClassViews, mods.hasFlag(Flags.CASE))
+ val {constrMods, vparamss} =
+ if (mods.hasFlag(Flags.TRAIT)) {NoMods, List()}
+ else {accessModifierOpt(),
+ paramClauses(name, implicitClassViews, mods.hasFlag(Flags.CASE))}
val thistpe = requiresTypeOpt()
- val template = classTemplate(mods, name, vparamss)
- val mods1 = if (mods.hasFlag(Flags.TRAIT) && (template.body forall treeInfo.isInterfaceMember))
+ val template = classTemplate(mods, name, constrMods, vparamss)
+ val mods1 = if (mods.hasFlag(Flags.TRAIT) &&
+ (template.body forall treeInfo.isInterfaceMember))
mods | Flags.INTERFACE
else mods
val result = ClassDef(mods1, name, tparams, thistpe, template)
@@ -1945,7 +1965,7 @@ trait Parsers requires SyntaxAnalyzer {
def objectDef(mods: Modifiers): ModuleDef =
atPos(in.skipToken()) {
val name = ident()
- val template = classTemplate(mods, name, List())
+ val template = classTemplate(mods, name, NoMods, List())
ModuleDef(mods, name, template)
}
@@ -1954,7 +1974,7 @@ trait Parsers requires SyntaxAnalyzer {
* MixinClassTemplate ::= [`extends' MixinParents] [[NewLine] TemplateBody]
* MixinParents ::= SimpleType {`with' SimpleType}
*/
- def classTemplate(mods: Modifiers, name: Name, vparamss: List[List[ValDef]]): Template =
+ def classTemplate(mods: Modifiers, name: Name, constrMods: Modifiers, vparamss: List[List[ValDef]]): Template =
atPos(in.currentPos) {
def acceptEmptyTemplateBody(msg: String): unit = {
if (in.token == LPAREN && settings.migrate.value)
@@ -1993,7 +2013,7 @@ trait Parsers requires SyntaxAnalyzer {
var body =
if (in.token == LBRACE) templateBody()
else { acceptEmptyTemplateBody("`{' expected"); List() }
- if (!mods.hasFlag(Flags.TRAIT)) Template(ps, vparamss, argss.toList, body)
+ if (!mods.hasFlag(Flags.TRAIT)) Template(ps, constrMods, vparamss, argss.toList, body)
else Template(ps, body)
}
@@ -2053,8 +2073,7 @@ trait Parsers requires SyntaxAnalyzer {
in.token == LBRACKET ||
isModifier) {
val attrs = attributeClauses()
- (stats ++
- joinAttributes(attrs, joinComment(List(tmplDef(modifiers()/*| mixinAttribute(attrs)*/)))))
+ stats ++ joinComment(List(tmplDef(modifiers() withAttributes attrs)))
} else if (in.token != SEMI && in.token != NEWLINE) {
syntaxErrorOrIncomplete("expected class or object definition", true)
}
@@ -2079,8 +2098,7 @@ trait Parsers requires SyntaxAnalyzer {
stats += expr()
} else if (isDefIntro || isModifier || in.token == LBRACKET) {
val attrs = attributeClauses()
- (stats ++
- joinAttributes(attrs, joinComment(defOrDcl(modifiers()/*| mixinAttribute(attrs)*/))))
+ stats ++ joinComment(defOrDcl(modifiers() withAttributes attrs))
} else if (in.token != SEMI && in.token != NEWLINE) {
syntaxErrorOrIncomplete("illegal start of definition", true)
}
@@ -2135,28 +2153,6 @@ trait Parsers requires SyntaxAnalyzer {
val constr = atPos(pos) { New(t, List(args)) }
glob.Attribute(constr, nameValuePairs) setPos pos
}
-/* //DEPRECATED
- def mixinAttribute(attrs: List[Tree]) = {
- def isMixinAttribute(attr: Tree) = attr match {
- case Apply(Select(New(Ident(name)), constr), List())
- if (name.toString() == "_mixin_" || name.toString() == "_trait_") =>
- true
- case _ =>
- false
- }
- if (attrs exists isMixinAttribute) Flags.TRAIT else 0
- }
-*/
- def joinAttributes(attrs: List[Attribute], defs: List[Tree]): List[Tree] = {
- def setAttr(defn: Tree): Unit = defn match {
- case DocDef(_, def0) => setAttr(def0)
- case m: MemberDef => m.mods setAttr attrs
- case _ => ()
- }
- if (!attrs.isEmpty)
- defs foreach setAttr
- defs
- }
/** TypeAttributes ::= (`[' Exprs `]') *
*
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index bbc5cde1dc..32b5f2bce2 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -142,7 +142,7 @@ abstract class TreeBuilder {
Block(
List(ClassDef(
Modifiers(FINAL | SYNTHETIC), x, List(), TypeTree(),
- Template(parents, List(List()), argss, stats))),
+ Template(parents, NoMods, List(List()), argss, stats))),
New(Ident(x), List(List())))
}
diff --git a/src/compiler/scala/tools/nsc/symtab/Flags.scala b/src/compiler/scala/tools/nsc/symtab/Flags.scala
index 2dbb5e6ffb..16b64b9aef 100644
--- a/src/compiler/scala/tools/nsc/symtab/Flags.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Flags.scala
@@ -132,7 +132,15 @@ object Flags {
var f = flags
val pw =
if (privateWithin == "") {
- ""
+ if ((flags & (PRIVATE | LOCAL)) == (PRIVATE | LOCAL)) {
+ f = f & ~(PRIVATE | LOCAL)
+ "private[this]"
+ } else if ((flags & (PROTECTED | LOCAL)) == (PROTECTED | LOCAL)) {
+ f = f & ~(PROTECTED | LOCAL)
+ "protected[this]"
+ } else {
+ ""
+ }
} else if ((f & PROTECTED) != 0) {
f = f & ~PROTECTED
"protected[" + privateWithin + "]"
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index 5d8fcac6b8..e9b2bd1b31 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -224,6 +224,10 @@ trait Symbols requires SymbolTable {
final def isStable =
isTerm && !hasFlag(MUTABLE) && (!hasFlag(METHOD | BYNAMEPARAM) || hasFlag(STABLE))
+ /** Is this symbol a private local */
+ final def isPrivateLocal =
+ hasFlag(PRIVATE) && hasFlag(LOCAL)
+
/** Does this symbol denote the primary constructor of its enclosing class? */
final def isPrimaryConstructor =
isConstructor && owner.primaryConstructor == this
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index 9ec52c2273..29e1ceeb1d 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -150,12 +150,11 @@ abstract class Constructors extends Transform {
val accessed = new TreeSet[Symbol]((x, y) => x isLess y)
- def isAccessed(sym: Symbol) = (
+ def isAccessed(sym: Symbol) =
sym.owner != clazz ||
!(sym hasFlag PARAMACCESSOR) ||
- !(sym hasFlag LOCAL) ||
+ !sym.isPrivateLocal ||
(accessed contains sym)
- );
val accessTraverser = new Traverser {
override def traverse(tree: Tree) = {
diff --git a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
index f170c132e7..b7b78f6258 100644
--- a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
+++ b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
@@ -24,8 +24,7 @@ abstract class OverridingPairs {
private val self = base.thisType
- protected def exclude(sym: Symbol): boolean =
- sym.isConstructor || (sym hasFlag LOCAL)
+ protected def exclude(sym: Symbol): boolean = sym.isConstructor || sym.isPrivateLocal
protected def parents: List[Type] = base.info.parents
@@ -115,7 +114,7 @@ abstract class OverridingPairs {
(overriding.owner == nextEntry.sym.owner) ||
(!matches(overriding, nextEntry.sym)) ||
(hasCommonParent(overriding, nextEntry.sym)) ||
- (overriding hasFlag LOCAL)))
+ (exclude(overriding))))
}
if (nextEntry ne null) {
overridden = nextEntry.sym;
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index b3feb1ed7f..3fb78e63b2 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -262,7 +262,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
localTyper.typed {
atPos(fun.pos) {
Block(
- List(ClassDef(anonClass, List(List()), List(List()), members)),
+ List(ClassDef(anonClass, NoMods, List(List()), List(List()), members)),
Typed(
New(TypeTree(anonClass.tpe), List(List())),
TypeTree(fun.tpe)))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index a77098a50f..0fb3d02cc5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -339,12 +339,19 @@ trait Contexts requires Analyzer {
def isSubClassOfEnclosing(clazz: Symbol): boolean =
enclosingSuperClassContext(clazz) != NoContext
+ def isSubThisType(pre: Type, clazz: Symbol): boolean = pre match {
+ case ThisType(pclazz) => pclazz isNonBottomSubClass clazz
+ case _ => false
+ }
+
(pre == NoPrefix) || {
val ab = sym.accessBoundary(sym.owner)
((ab == NoSymbol)
||
(accessWithin(ab) || accessWithin(ab.linkedClassOfClass)) &&
- (!sym.hasFlag(LOCAL) || pre =:= sym.owner.thisType)
+ (!sym.hasFlag(LOCAL) ||
+ (sym hasFlag PROTECTED) && isSubThisType(pre, sym.owner) ||
+ pre =:= sym.owner.thisType)
||
(sym hasFlag PROTECTED) &&
(superAccess ||
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 4bede93d85..eb803266e0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -269,7 +269,7 @@ trait Namers requires Analyzer {
tree.symbol.moduleClass.setInfo(namerOf(tree.symbol).moduleClassTypeCompleter(tree))
finish
case ValDef(mods, name, tp, rhs) =>
- if (context.owner.isClass & (mods.flags & LOCAL) == 0) {
+ if (context.owner.isClass && (mods.flags & (PRIVATE | LOCAL)) != (PRIVATE | LOCAL)) {
val accflags = ACCESSOR |
(if ((mods.flags & MUTABLE) != 0) mods.flags & ~MUTABLE else mods.flags | STABLE)
val getter = owner.newMethod(tree.pos, name).setFlag(accflags)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index d35f5d8e21..a07f4c472e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -464,6 +464,15 @@ trait Typers requires Analyzer {
else tree
}
+ /** The member with givne name of given qualifier tree */
+ def member(qual: Tree, name: Name) = qual.tpe match {
+ case ThisType(clazz) if (context.enclClass.owner.ownerChain contains clazz) =>
+ qual.tpe.member(name)
+ case _ =>
+ if (phase.next.erasedTypes) qual.tpe.member(name)
+ else qual.tpe.nonLocalMember(name)
+ }
+
/** Perform the following adaptations of expression, pattern or type `tree' wrt to
* given mode `mode' and given prototype `pt':
* (0) Convert expressions with constant types to literals
@@ -582,9 +591,10 @@ trait Typers requires Analyzer {
}
}
} else if ((mode & (EXPRmode | FUNmode)) == (EXPRmode | FUNmode) &&
- !tree.tpe.isInstanceOf[MethodType] && !tree.tpe.isInstanceOf[OverloadedType] &&
+ !tree.tpe.isInstanceOf[MethodType] &&
+ !tree.tpe.isInstanceOf[OverloadedType] &&
((mode & TAPPmode) == 0 || tree.tpe.typeParams.isEmpty) &&
- adaptToName(tree, nme.apply).tpe.nonLocalMember(nme.apply)
+ member(adaptToName(tree, nme.apply), nme.apply)
.filter(m => m.tpe.paramSectionCount > 0) != NoSymbol) { // (8)
val qual = adaptToName(tree, nme.apply) match {
case id @ Ident(_) =>
@@ -676,7 +686,7 @@ trait Typers requires Analyzer {
}
def adaptToName(qual: Tree, name: Name) =
- if (qual.tpe.nonLocalMember(name) != NoSymbol) qual
+ if (member(qual, name) != NoSymbol) qual
else adaptToMember(qual, name, WildcardType)
private def completeParentType(tpt: Tree, tparams: List[Symbol], enclTparams: List[Symbol], vparamss: List[List[ValDef]], superargs: List[Tree]): Type = {
@@ -830,7 +840,7 @@ trait Typers requires Analyzer {
*/
def addGetterSetter(stat: Tree): List[Tree] = stat match {
case ValDef(mods, name, tpt, rhs)
- if !(mods hasFlag LOCAL) && !stat.symbol.isModuleVar =>
+ if (mods.flags & (PRIVATE | LOCAL)) != (PRIVATE | LOCAL) && !stat.symbol.isModuleVar =>
val vdef = copy.ValDef(stat, mods | PRIVATE | LOCAL, nme.getterToLocal(name), tpt, rhs)
val value = vdef.symbol
val getter = if (mods hasFlag DEFERRED) value else value.getter(value.owner)
@@ -843,8 +853,8 @@ trait Typers requires Analyzer {
else typed(atPos(vdef.pos)(Select(This(value.owner), value)), EXPRmode, value.tpe))
result.tpt.asInstanceOf[TypeTree] setOriginal tpt /* setPos tpt.pos */
checkNoEscaping.privates(getter, result.tpt)
- result.mods setAttr vdef.mods.attributes
- result
+ copy.DefDef(result, result.mods withAttributes vdef.mods.attributes, result.name,
+ result.tparams, result.vparamss, result.tpt, result.rhs)
}
def setterDef: DefDef = {
val setr = getter.setter(value.owner)
@@ -855,8 +865,8 @@ trait Typers requires Analyzer {
else
typed(Assign(Select(This(value.owner), value),
Ident(vparamss.head.head)))))
- result.mods setAttr vdef.mods.attributes
- result
+ copy.DefDef(result, result.mods withAttributes vdef.mods.attributes, result.name,
+ result.tparams, result.vparamss, result.tpt, result.rhs)
}
val gs = if (mods hasFlag MUTABLE) List(getterDef, setterDef)
else List(getterDef)
@@ -1257,6 +1267,7 @@ trait Typers requires Analyzer {
}
def typedImport(imp : Import) : Import = imp;
+
def typedStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = {
val inBlock = exprOwner == context.owner
def typedStat(stat: Tree): Tree = {
@@ -1276,19 +1287,21 @@ trait Typers requires Analyzer {
localTyper.typed(stat)
}
}
+ def accesses(accessor: Symbol, accessed: Symbol) =
+ (accessed hasFlag LOCAL) && (accessed hasFlag PARAMACCESSOR) ||
+ (accessor hasFlag ACCESSOR) &&
+ !(accessed hasFlag ACCESSOR) && accessed.isPrivateLocal
def checkNoDoubleDefs(stats: List[Tree]) = {
val scope = if (inBlock) context.scope else context.owner.info.decls;
var e = scope.elems;
while ((e ne null) && e.owner == scope) {
- if (!e.sym.hasFlag(LOCAL)) {
- var e1 = scope.lookupNextEntry(e);
- while ((e1 ne null) && e1.owner == scope) {
- if (!e1.sym.hasFlag(LOCAL) &&
- (e.sym.isType || inBlock || (e.sym.tpe matches e1.sym.tpe)))
- if (!e.sym.isErroneous && !e1.sym.isErroneous)
- error(e.sym.pos, e1.sym+" is defined twice");
- e1 = scope.lookupNextEntry(e1);
- }
+ var e1 = scope.lookupNextEntry(e);
+ while ((e1 ne null) && e1.owner == scope) {
+ if (!accesses(e.sym, e1.sym) && !accesses(e1.sym, e.sym) &&
+ (e.sym.isType || inBlock || (e.sym.tpe matches e1.sym.tpe)))
+ if (!e.sym.isErroneous && !e1.sym.isErroneous)
+ error(e.sym.pos, e1.sym+" is defined twice");
+ e1 = scope.lookupNextEntry(e1);
}
e = e.next
}
@@ -1630,12 +1643,8 @@ trait Typers requires Analyzer {
"\n phase = "+phase)
}
tree.symbol
- } else qual.tpe match {
- case ThisType(clazz) if (context.enclClass.owner.ownerChain contains clazz) =>
- qual.tpe.member(name)
- case _ =>
- if (phase.next.erasedTypes) qual.tpe.member(name)
- else qual.tpe.nonLocalMember(name)
+ } else {
+ member(qual, name)
}
if (sym == NoSymbol && name != nme.CONSTRUCTOR && (mode & EXPRmode) != 0) {
val qual1 = adaptToName(qual, name)