diff options
author | Martin Odersky <odersky@gmail.com> | 2006-08-16 14:00:59 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2006-08-16 14:00:59 +0000 |
commit | 840911b8e30c0ef203a087ca4d91a24f148f3dd9 (patch) | |
tree | 48ff5d4a7276962ec71d09c15070458ae2136cd4 | |
parent | 49ee6e4ec40b8739e0f86c3ec23b7742e423f12f (diff) | |
download | scala-840911b8e30c0ef203a087ca4d91a24f148f3dd9.tar.gz scala-840911b8e30c0ef203a087ca4d91a24f148f3dd9.tar.bz2 scala-840911b8e30c0ef203a087ca4d91a24f148f3dd9.zip |
allowed access to provates between a class and ...
allowed access to provates between a class and its companion module
13 files changed, 79 insertions, 44 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index 614c5ad874..cff53734fe 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -172,10 +172,10 @@ abstract class GenJVM extends SubComponent { addStaticInit(jclass); if (isTopLevelModule(c.symbol)) { - if (c.symbol.linkedClass == NoSymbol) + if (c.symbol.linkedClassOfModule == NoSymbol) dumpMirrorClass; - else if (c.symbol.linkedClass != NoSymbol && - !currentRun.compiles(c.symbol.linkedClass)) { + else if (c.symbol.linkedClassOfModule != NoSymbol && + !currentRun.compiles(c.symbol.linkedClassOfModule)) { log("Dumping mirror class for " + c.symbol + " even though linked class exists, but is not compiled in this run"); dumpMirrorClass; } else diff --git a/src/compiler/scala/tools/nsc/symtab/Constants.scala b/src/compiler/scala/tools/nsc/symtab/Constants.scala index 181ab56ef1..cdca0502da 100644 --- a/src/compiler/scala/tools/nsc/symtab/Constants.scala +++ b/src/compiler/scala/tools/nsc/symtab/Constants.scala @@ -62,7 +62,7 @@ trait Constants requires SymbolTable { case StringTag => StringClass.tpe case NullTag => AllRefClass.tpe case ClassTag => ClassClass.tpe - case EnumTag => symbolValue.owner.linkedClass.tpe + case EnumTag => symbolValue.owner.linkedClassOfClass.tpe } /** We need the equals method to take account of tags as well as values */ diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala index 5611af7b1e..0136ab82a8 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala @@ -52,14 +52,6 @@ abstract class SymbolLoaders { if (root.rawInfo == this && root.linkedSym.rawInfo == this) throw new TypeError(source + " does not define " + root) ok = true; -/* - val sourceFile0 = if (sourceFile == null) (root match { - case clazz: ClassSymbol => clazz.sourceFile; - case _ => null; - }) else sourceFile; - setSource(root.linkedModule.moduleClass, sourceFile0); - setSource(root.linkedClass, sourceFile0); -*/ } catch { case ex: IOException => ok = false; @@ -124,8 +116,8 @@ abstract class SymbolLoaders { module.moduleClass.sourceFile = completer.sourceFile } */ - assert(clazz.linkedModule == module, module); - assert(module.linkedClass == clazz, clazz); + assert(clazz.linkedModuleOfClass == module, module); + assert(module.linkedClassOfModule == clazz, clazz); } val classes = new HashMap[String, global.classPath0.Context]; diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index c97ae9eef5..68c1e0d070 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -580,11 +580,15 @@ trait Symbols requires SymbolTable { * an alias, NoSymbol for all others */ def alias: Symbol = NoSymbol + /** The top-level class containing this symbol */ + def toplevelClass: Symbol = + if (isClass && owner.isPackageClass) this else owner.toplevelClass + /** The class with the same name in the same package as this module or * case class factory */ - final def linkedClass: Symbol = { - if (this != NoSymbol && owner.isPackageClass) + final def linkedClassOfModule: Symbol = { + if (this != NoSymbol) owner.info.decl(name.toTypeName).suchThat(sym => sym.rawInfo ne NoType) else NoSymbol } @@ -592,23 +596,23 @@ trait Symbols requires SymbolTable { /** The module or case class factory with the same name in the same * package as this class. */ - final def linkedModule: Symbol = - if (owner.isPackageClass) + final def linkedModuleOfClass: Symbol = + if (this != NoSymbol) owner.info.decl(name.toTermName).suchThat( sym => (sym hasFlag MODULE) && (sym.rawInfo ne NoType)) else NoSymbol - /** The top-level class containing this symbol */ - def toplevelClass: Symbol = - if (isClass && owner.isPackageClass) this else owner.toplevelClass - /** For a module its linked class, for a class its linked module or case factory otherwise */ final def linkedSym: Symbol = - if (isTerm) linkedClass - else if (isClass && owner.isPackageClass) - owner.info.decl(name.toTermName).suchThat(sym => sym.rawInfo ne NoType) + if (isTerm) linkedClassOfModule + else if (isClass) owner.info.decl(name.toTermName).suchThat(sym => sym.rawInfo ne NoType) else NoSymbol + /** For a module class its linked class, for a plain class + * the module class of itys linked module */ + final def linkedClassOfClass: Symbol = + if (isModuleClass) linkedClassOfModule else linkedModuleOfClass.moduleClass + final def toInterface: Symbol = if (isImplClass) { assert(!tpe.parents.isEmpty, this) @@ -1051,7 +1055,7 @@ trait Symbols requires SymbolTable { clone } - override def sourceModule = if (isModuleClass) linkedModule else NoSymbol + override def sourceModule = if (isModuleClass) linkedModuleOfClass else NoSymbol if (util.Statistics.enabled) classSymbolCount = classSymbolCount + 1 } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 34f68f9f67..1c539f9400 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -71,11 +71,11 @@ abstract class ClassfileParser { this.in = new AbstractFileReader(file) if (root.isModule) { - this.clazz = root.linkedClass + this.clazz = root.linkedClassOfModule this.staticModule = root } else { this.clazz = root - this.staticModule = root.linkedModule + this.staticModule = root.linkedModuleOfClass } this.isScala = false this.hasMeta = false @@ -181,10 +181,10 @@ abstract class ClassfileParser { in.buf(start) != CONSTANT_METHODREF && in.buf(start) != CONSTANT_INTFMETHODREF) errorBadTag(start) val cls = getClassSymbol(in.getChar(start + 1)) - val Pair(name, tpe) = getNameAndType(in.getChar(start + 3), cls); - f = ((if (static) cls.linkedModule.moduleClass else cls) - .info.decl(name).suchThat(s => s.tpe =:= tpe)); - assert(f != NoSymbol, "Could not find symbol for " + name + ": " + tpe + " in " + cls); + val Pair(name, tpe) = getNameAndType(in.getChar(start + 3), cls) + val owner = if (static) cls.linkedClassOfClass else cls + f = owner.info.decl(name).suchThat(.tpe.=:=(tpe)) + assert(f != NoSymbol, "Could not find symbol for " + name + ": " + tpe + " in " + owner) values(index) = f } f @@ -524,7 +524,7 @@ abstract class ClassfileParser { def parseAttribute(): unit = { val attrName = pool.getName(in.nextChar) val attrLen = in.nextInt - val oldpb = in.bp; + val oldpb = in.bp attrName match { case nme.SignatureATTR => if (global.settings.Xgenerics.value) { @@ -554,7 +554,7 @@ abstract class ClassfileParser { if (!isScala) parseInnerClasses() else in.skip(attrLen) case nme.ScalaSignatureATTR => unpickler.unpickle(in.buf, in.bp, clazz, staticModule, in.file.toString()) - in.skip(attrLen); + in.skip(attrLen) this.isScala = true case nme.JacoMetaATTR => val meta = pool.getName(in.nextChar).toString().trim() @@ -599,7 +599,7 @@ abstract class ClassfileParser { case ENUM_TAG => val t = pool.getType(index) val n = pool.getName(in.nextChar) - val s = t.symbol.linkedModule.info.decls.lookup(n) + val s = t.symbol.linkedModuleOfClass.info.decls.lookup(n) //assert (s != NoSymbol, "while processing " + in.file + ": " + t + "." + n + ": " + t.decls) assert(s != NoSymbol, t) // avoid string concatenation! Constant(s) diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala index 4ca47c72a9..6491f4e186 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala @@ -29,7 +29,7 @@ abstract class ICodeReader extends ClassfileParser { assert(cls.classFile ne null, "No classfile for " + cls); this.instanceCode = new IClass(cls); - this.staticCode = new IClass(cls.linkedClass); + this.staticCode = new IClass(cls.linkedClassOfModule); parse(cls.classFile, cls); Pair(staticCode, instanceCode) diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/SymblfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/SymblfileParser.scala index f8fa046bf4..c17e41e88f 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/SymblfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/SymblfileParser.scala @@ -29,9 +29,9 @@ abstract class SymblfileParser { current = file val in = new AbstractFileReader(file) if (root.isModule) - unpickler.unpickle(in.buf, 0, root.linkedClass, root, file.toString()) + unpickler.unpickle(in.buf, 0, root.linkedClassOfModule, root, file.toString()) else - unpickler.unpickle(in.buf, 0, root, root.linkedModule, file.toString()) + unpickler.unpickle(in.buf, 0, root, root.linkedModuleOfClass, file.toString()) current = null } } diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index 6c02ea65be..610d9caab5 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -36,7 +36,7 @@ abstract class CleanUp extends Transform { case Some(meth) => meth case None => - val forName = getMember(ClassClass.linkedModule, nme.forName) + val forName = getMember(ClassClass.linkedModuleOfClass, nme.forName) val owner = currentOwner.enclClass val cvar = owner.newVariable(pos, freshClassConstantVarName()) diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index c14e9c5c9f..98dfb5ef24 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -171,7 +171,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { else BoxedObjectArrayClass; Apply(Select(New(TypeTree(boxedClass.tpe)), nme.CONSTRUCTOR), List(tree)) } else { - val boxedModule = boxedClass(tree.tpe.symbol).linkedModule; + val boxedModule = boxedClass(tree.tpe.symbol).linkedModuleOfClass; Apply(Select(gen.mkAttributedRef(boxedModule), nme.box), List(tree)) } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 383d22a447..22d792bc4f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -243,7 +243,8 @@ trait Contexts requires Analyzer { || (!sym.hasFlag(PRIVATE | PROTECTED)) || - accessWithin(sym.owner) && (!sym.hasFlag(LOCAL) || pre =:= sym.owner.thisType) + (accessWithin(sym.owner) || accessWithin(sym.owner.linkedClassOfClass)) && + (!sym.hasFlag(LOCAL) || pre =:= sym.owner.thisType) || (!sym.hasFlag(PRIVATE) && (superAccess || diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 031012aee2..2c9797b0dc 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1916,7 +1916,7 @@ trait Typers requires Analyzer { def isSubClassOrObject(sym1: Symbol, sym2: Symbol) = { (sym1 isSubClass sym2) || sym1.isModuleClass && sym2.isModuleClass && - (sym1.sourceModule.linkedClass isSubClass sym2.sourceModule.linkedClass) + (sym1.linkedClassOfClass isSubClass sym2.linkedClassOfClass) } def improves(info1: ImplicitInfo, info2: ImplicitInfo) = (info2 == NoImplicitInfo) || @@ -1951,8 +1951,8 @@ trait Typers requires Analyzer { } def implicitsOfClass(clazz: Symbol): List[ImplicitInfo] = ( - clazz.initialize.linkedModule.moduleClass.info.members.toList.filter(.hasFlag(IMPLICIT)) map - (sym => new ImplicitInfo(sym.name, clazz.linkedModule.tpe, sym)) + clazz.initialize.linkedClassOfClass.info.members.toList.filter(.hasFlag(IMPLICIT)) map + (sym => new ImplicitInfo(sym.name, clazz.linkedModuleOfClass.tpe, sym)) ) var tree = searchImplicit(context.implicitss, true) diff --git a/test/files/neg/gadts1.check b/test/files/neg/gadts1.check new file mode 100644 index 0000000000..8b3d6605ed --- /dev/null +++ b/test/files/neg/gadts1.check @@ -0,0 +1,11 @@ +gadts1.scala:15 error: type mismatch; + found : Test.this.NumTerm + required: Test.this.Term[a] + case NumTerm(n) => c.x = Double(1.0) + ^ +gadts1.scala:15 error: type mismatch; + found : Test.this.Double + required: a + case NumTerm(n) => c.x = Double(1.0) + ^ +two errors found diff --git a/test/files/neg/gadts1.scala b/test/files/neg/gadts1.scala new file mode 100755 index 0000000000..67aef4f2d9 --- /dev/null +++ b/test/files/neg/gadts1.scala @@ -0,0 +1,27 @@ +object Test{ + +abstract class Number +case class Int(n: int) extends Number +case class Double(d: double) extends Number + +trait Term[+a] +case class Cell[a](var x: a) extends Term[a] +case class NumTerm(val n: Number) extends Term[Number] +class IntTerm(n: Int) extends NumTerm(n) with Term[Int] + + +def f[a](t:Term[a], c:Cell[a]): unit = + t match { + case NumTerm(n) => c.x = Double(1.0) + } + + +val x:Term[Number] = NumTerm(Int(5)) + +def main(args: Array[String]): unit = { + val cell = Cell[Int](Int(6)) + Console.println(cell) + f[Int](new IntTerm(Int(5)), cell) + Console.println(cell) +} +} |