summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2007-11-01 17:35:15 +0000
committerMartin Odersky <odersky@gmail.com>2007-11-01 17:35:15 +0000
commit3a4750825e3b3992adcddd4666f264d508e21f7a (patch)
tree1ed1eae169a180c46ceb23a3ab93a00d0e5deed0 /src
parentb14c210baba254900b2b999b4c648526a5a7846e (diff)
downloadscala-3a4750825e3b3992adcddd4666f264d508e21f7a.tar.gz
scala-3a4750825e3b3992adcddd4666f264d508e21f7a.tar.bz2
scala-3a4750825e3b3992adcddd4666f264d508e21f7a.zip
fixed ticket 91
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala21
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala12
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala21
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala15
5 files changed, 47 insertions, 24 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index c90ea60b12..6bc136e976 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -208,13 +208,20 @@ abstract class TreeGen {
ValDef(mvar, if (mvar.owner.isClass) EmptyTree else Literal(Constant(null)))
}
- // def m: T = { if (m$ eq null) m$ = new m$class; m$ }
- def mkModuleAccessDef(accessor: Symbol, mvar: Symbol) =
- DefDef(accessor, vparamss =>
- mkCached(mvar,
- New(TypeTree(mvar.tpe),
- List(for (pt <- mvar.tpe.typeSymbol.primaryConstructor.info.paramTypes)
- yield This(accessor.owner.enclClass)))))
+ // def m: T = { if (m$ eq null) m$ = new m$class(...) m$ }
+ // where (...) are eventual outer accessors
+ def mkCachedModuleAccessDef(accessor: Symbol, mvar: Symbol) =
+ DefDef(accessor, vparamss => mkCached(mvar, newModule(accessor, mvar.tpe)))
+
+ // def m: T = new tpe(...)
+ // where (...) are eventual outer accessors
+ def mkModuleAccessDef(accessor: Symbol, tpe: Type) =
+ DefDef(accessor, vparamss => newModule(accessor, tpe))
+
+ private def newModule(accessor: Symbol, tpe: Type) =
+ New(TypeTree(tpe),
+ List(for (pt <- tpe.typeSymbol.primaryConstructor.info.paramTypes)
+ yield This(accessor.owner.enclClass)))
// def m: T;
def mkModuleAccessDcl(accessor: Symbol) =
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index 0b801fca89..c735c953bf 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -611,6 +611,18 @@ trait Symbols {
def getAttributes(clazz: Symbol): List[AnnotationInfo] =
attributes.filter(_.atp.typeSymbol.isNonBottomSubClass(clazz))
+ /** The least proper supertype of a class; includes all parent types
+ * and refinement where needed */
+ def classBound: Type = {
+ val tp = refinedType(info.parents, owner)
+ val thistp = tp.typeSymbol.thisType
+ for (sym <- info.decls.toList) {
+ if (sym.isPublic && !sym.isClass && !sym.isConstructor)
+ addMember(thistp, tp, sym.cloneSymbol(tp.typeSymbol).setInfo(sym.info))
+ }
+ tp
+ }
+
/** Reset symbol to initial state
*/
def reset(completer: Type) {
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index 7289468406..9803294ae9 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -630,7 +630,7 @@ abstract class Mixin extends InfoTransform {
// add modules
val vdef = gen.mkModuleVarDef(sym)
addDef(position(sym), vdef)
- addDef(position(sym), gen.mkModuleAccessDef(sym, vdef.symbol))
+ addDef(position(sym), gen.mkCachedModuleAccessDef(sym, vdef.symbol))
} else if (!sym.isMethod) {
// add fields
addDef(position(sym), ValDef(sym))
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index fb10d2b1b2..ffecaf5a39 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -598,8 +598,23 @@ abstract class RefChecks extends InfoTransform {
.setPos(tree.pos)
.setSymbol(sym.moduleClass)
.setType(NoType);
- if (sym.isStatic) List(transform(cdef))
- else {
+ if (sym.isStatic) {
+ if (!sym.allOverriddenSymbols.isEmpty) {
+ val factory = sym.owner.newMethod(sym.pos, sym.name)
+ .setFlag(sym.flags | STABLE).resetFlag(MODULE)
+ .setInfo(PolyType(List(), sym.moduleClass.tpe))
+ sym.owner.info.decls.enter(factory)
+ val ddef =
+ atPhase(phase.next) {
+ localTyper.typed {
+ gen.mkModuleAccessDef(factory, sym.tpe)
+ }
+ }
+ transformTrees(List(cdef, ddef))
+ } else {
+ List(transform(cdef))
+ }
+ } else {
val vdef =
localTyper.typed {
atPos(tree.pos) {
@@ -611,7 +626,7 @@ abstract class RefChecks extends InfoTransform {
atPhase(phase.next) {
localTyper.typed {
if (sym.owner.isTrait) gen.mkModuleAccessDcl(sym)
- else gen.mkModuleAccessDef(sym, vdef.symbol)
+ else gen.mkCachedModuleAccessDef(sym, vdef.symbol)
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index ab07c52a07..ef56d827c4 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -358,7 +358,7 @@ trait Typers { self: Analyzer =>
else if (hiddenSymbols exists (_.isErroneous)) setError(tree)
else if (isFullyDefined(pt)) tree setType pt //todo: eliminate
else if (tp1.typeSymbol.isAnonymousClass) // todo: eliminate
- check(owner, scope, pt, tree setType classBound(tp1.typeSymbol))
+ check(owner, scope, pt, tree setType tp1.typeSymbol.classBound)
else if (owner == NoSymbol)
tree setType packSymbols(hiddenSymbols.reverse, tp1)
else { // privates
@@ -1331,16 +1331,6 @@ trait Typers { self: Analyzer =>
copy.LabelDef(ldef, ldef.name, ldef.params, rhs1) setType restpe
}
- def classBound(clazz: Symbol): Type = {
- val tp = refinedType(clazz.info.parents, clazz.owner)
- val thistp = tp.typeSymbol.thisType
- for (sym <- clazz.info.decls.toList) {
- if (sym.isPublic && !sym.isClass && !sym.isConstructor)
- addMember(thistp, tp, sym.cloneSymbol(tp.typeSymbol).setInfo(sym.info))
- }
- tp
- }
-
protected def typedFunctionIDE(fun : Function, txt : Context) = {}
/**
@@ -1857,8 +1847,7 @@ trait Typers { self: Analyzer =>
protected def existentialBound(sym: Symbol): Type =
if (sym.isClass)
- parameterizedType(
- sym.typeParams, mkTypeBounds(AllClass.tpe, classBound(sym)))
+ parameterizedType(sym.typeParams, mkTypeBounds(AllClass.tpe, sym.classBound))
else if (sym.isAbstractType)
sym.info
else if (sym.isTerm)