Fixed #2545. Fixed problem with cyclic dependcies when adding package objects. Prepared for module expansion to lazy vals.

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@19375 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
odersky 2009-11-02 16:48:56 +00:00
parent 44b5142d4d
commit 8bfe94c595
9 changed files with 93 additions and 21 deletions

View File

@ -516,6 +516,18 @@ QUICK BUILD (QUICK)
<pathelement location="${build-quick.dir}/classes/library"/>
</compilationpath>
</scalacfork>
<scalacfork
destdir="${build-quick.dir}/classes/library"
compilerpathref="locker.classpath"
srcpath="${src.dir}/library"
params="${scalac.args.quick}"
srcdir="${src.dir}/swing"
jvmargs="${scalacfork.jvmargs}">
<include name="scala/swing/package.scala"/>
<compilationpath>
<pathelement location="${build-quick.dir}/classes/library"/>
</compilationpath>
</scalacfork>
<scalacfork
destdir="${build-quick.dir}/classes/library"
compilerpathref="locker.classpath"
@ -524,6 +536,7 @@ QUICK BUILD (QUICK)
srcdir="${src.dir}/swing"
jvmargs="${scalacfork.jvmargs}">
<include name="**/*.scala"/>
<exclude name="scala/swing/package.scala"/>
<compilationpath>
<pathelement location="${build-quick.dir}/classes/library"/>
</compilationpath>
@ -963,6 +976,14 @@ BOOTSTRAPPING BUILD (STRAP)
addparams="${scalac.args.all}">
<include name="**/*.scala"/>
</scalac>
<scalac
srcdir="${src.dir}/swing"
destdir="${build-strap.dir}/classes/library"
classpath="${build-strap.dir}/classes/library"
target="jvm-1.5"
addparams="${scalac.args.all}">
<include name="scala/swing/package.scala"/>
</scalac>
<scalac
srcdir="${src.dir}/swing"
destdir="${build-strap.dir}/classes/library"
@ -970,6 +991,7 @@ BOOTSTRAPPING BUILD (STRAP)
target="jvm-1.5"
addparams="${scalac.args.all}">
<include name="**/*.scala"/>
<exclude name="scala/swing/package.scala"/>
</scalac>
<propertyfile file="${build-strap.dir}/classes/library/library.properties">
<entry key="version.number" value="${version.number}"/>

View File

@ -239,6 +239,20 @@ abstract class TreeGen
)
}
// var m$: T = null; or, if class member: local var m$: T = _;
/*!!!
def mkModuleValDef(accessor: Symbol) = {
val mval = accessor.owner.newValue(accessor.pos.focus, nme.moduleVarName(accessor.name))
.setInfo(accessor.tpe.finalResultType)
.setFlag(LAZY);
if (mval.owner.isClass) {
mval setFlag (PRIVATE | LOCAL | SYNTHETIC)
mval.owner.info.decls.enter(mval)
}
ValDef(mval, New(TypeTree(mval.tpe), List(List())))
}
*/
// var m$: T = null; or, if class member: local var m$: T = _;
def mkModuleVarDef(accessor: Symbol) = {
val mvar = accessor.owner.newVariable(accessor.pos.focus, nme.moduleVarName(accessor.name))

View File

@ -164,9 +164,10 @@ abstract class SymbolLoaders {
// if there's a $member object, enter its members as well.
val pkgModule = root.info.decl(nme.PACKAGEkw)
if (pkgModule.isModule && !(pkgModule.rawInfo.isInstanceOf[SourcefileLoader] &&
classpath.name == "scala"))
if (pkgModule.isModule && !pkgModule.rawInfo.isInstanceOf[SourcefileLoader]) {
//println("open "+pkgModule)//DEBUG
openPackageModule(pkgModule)
}
}
}

View File

@ -359,9 +359,6 @@ trait Namers { self: Analyzer =>
tree.symbol = enterModuleSymbol(tree)
tree.symbol.moduleClass.setInfo(namerOf(tree.symbol).moduleClassTypeCompleter((tree)))
finish
if (tree.symbol.name == nme.PACKAGEkw && tree.symbol.owner != ScalaPackageClass) {
loaders.openPackageModule(tree.symbol)
}
case vd @ ValDef(mods, name, tp, rhs) =>
if ((!context.owner.isClass ||
@ -392,7 +389,7 @@ trait Namers { self: Analyzer =>
if (mods.isDeferred) {
getter setPos tree.pos // unfocus getter position, because there won't be a separate value
} else {
var vsym =
val vsym =
if (!context.owner.isClass) {
assert(mods.isLazy) // if not a field, it has to be a lazy val
owner.newValue(tree.pos, name + "$lzy" ).setFlag(mods.flags | MUTABLE)
@ -1132,14 +1129,13 @@ trait Namers { self: Analyzer =>
newNamer(context.makeNewScope(tree, sym)).classSig(tparams, impl)
case ModuleDef(_, _, impl) =>
/** no, does not work here.
if (tree.symbol.name == nme.PACKAGEkw) {
loaders.openPackageModule(tree.symbol)
}
*/
val clazz = sym.moduleClass
clazz.setInfo(newNamer(context.makeNewScope(tree, clazz)).templateSig(impl))
//clazz.typeOfThis = singleType(sym.owner.thisType, sym);
tree.symbol.setInfo(clazz.tpe) // initialize module to avoid cycles
if (tree.symbol.name == nme.PACKAGEkw) {
loaders.openPackageModule(tree.symbol)
}
clazz.tpe
case DefDef(mods, _, tparams, vparamss, tpt, rhs) =>

View File

@ -780,7 +780,7 @@ abstract class RefChecks extends InfoTransform {
val cdef = ClassDef(mods | MODULE, name, List(), impl)
.setPos(tree.pos)
.setSymbol(sym.moduleClass)
.setType(NoType);
.setType(NoType)
if (sym.isStatic) {
if (!sym.allOverriddenSymbols.isEmpty) {
val factory = sym.owner.newMethod(sym.pos, sym.name)

View File

@ -1420,10 +1420,17 @@ trait Typers { self: Analyzer =>
templ setSymbol clazz.newLocalDummy(templ.pos)
val self1 = templ.self match {
case vd @ ValDef(mods, name, tpt, EmptyTree) =>
val tpt1 = checkNoEscaping.privates(clazz.thisSym, typedType(tpt))
val tpt1 =
checkNoEscaping.privates(
clazz.thisSym,
treeCopy.TypeTree(tpt) setType vd.symbol.tpe)
treeCopy.ValDef(vd, mods, name, tpt1, EmptyTree) setType NoType
}
if (self1.name != nme.WILDCARD) context.scope enter self1.symbol
// was:
// val tpt1 = checkNoEscaping.privates(clazz.thisSym, typedType(tpt))
// treeCopy.ValDef(vd, mods, name, tpt1, EmptyTree) setType NoType
// but this leads to cycles for existential self types ==> #2545
if (self1.name != nme.WILDCARD) context.scope enter self1.symbol
val selfType =
if (clazz.isAnonymousClass && !phase.erasedTypes)
intersectionType(clazz.info.parents, clazz.owner)
@ -2944,13 +2951,18 @@ trait Typers { self: Analyzer =>
.setOriginal(tpt1)
.setType(appliedType(tpt1.tpe, context.undetparams map (_.tpe)))
}
/** If current tree <tree> appears in <val x(: T)? = <tree>>
* return `tp with x.type' else return `tp'.
*/
def narrowRhs(tp: Type) = {
var sym = context.tree.symbol
if (sym != null && sym != NoSymbol && sym.owner.isClass && sym.getter(sym.owner) != NoSymbol)
sym = sym.getter(sym.owner)
if (sym != null && sym != NoSymbol)
if (sym.owner.isClass) {
if (sym.getter(sym.owner) != NoSymbol) sym = sym.getter(sym.owner)
} else if (sym hasFlag LAZY) {
if (sym.lazyAccessor != NoSymbol) sym = sym.lazyAccessor
}
context.tree match {
case ValDef(mods, _, _, Apply(Select(`tree`, _), _)) if !(mods hasFlag MUTABLE) =>
val pre = if (sym.owner.isClass) sym.owner.thisType else NoPrefix

View File

@ -11,7 +11,7 @@
package object scala {
type Travarsable[+A] = scala.collection.Traversable[A]
type Traversable[+A] = scala.collection.Traversable[A]
val Traversable = scala.collection.Traversable
type Iterable[+A] = scala.collection.Iterable[A]

View File

@ -11,10 +11,11 @@
package scala.util.control
/** An object that can be used for the break control abstraction.
/** A class that can be instantiated for the break control abstraction.
* Example usage:<pre>
*
* <b>import</b> Breaks.{break, breakable}
* val mybreaks = new Breaks
* import</b> mybreaks.{break, breakable}
*
* breakable {
* <b>for</b> (...) {
@ -22,6 +23,8 @@ package scala.util.control
* }
* }</pre>
*
* Calls to break from one instantiation of Breaks will never
* target breakable objects of some other instantion.
*/
class Breaks {
@ -37,11 +40,25 @@ class Breaks {
}
}
/* Break from closest enclosing breakable block */
/* Break from dynamically closest enclosing breakable block
* @note this might be different than the statically closest enclosing
* block!
*/
def break { throw breakException }
}
/** A singleton object providing the Break functionality */
/** An object that can be used for the break control abstraction.
* Example usage:<pre>
*
* <b>import</b> Breaks.{break, breakable}
*
* breakable {
* <b>for</b> (...) {
* <b>if</b> (...) break
* }
* }</pre>
*
*/
object Breaks extends Breaks
private class BreakException extends RuntimeException with ControlException

10
test/files/pos/t2545.scala Executable file
View File

@ -0,0 +1,10 @@
trait Frog[T] {
def hello: T
def size: Int
}
trait OnlyWithFrogs {
self: Frog[_] =>
def sizeStr = size.toString
}