summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-05-02 13:19:07 -0700
committerPaul Phillips <paulp@improving.org>2012-05-02 13:19:07 -0700
commitbf0f008df8feb8357fcad9aa455ff63b409d59bf (patch)
treec452b12808f6a4513fd1013655a339f242978f68
parent4b8c54cd9e52dbacc239d05c8149d7f249bbebab (diff)
parent77b577a5aeab782b64b39b3a812c35fdd8ab265a (diff)
downloadscala-bf0f008df8feb8357fcad9aa455ff63b409d59bf.tar.gz
scala-bf0f008df8feb8357fcad9aa455ff63b409d59bf.tar.bz2
scala-bf0f008df8feb8357fcad9aa455ff63b409d59bf.zip
Merge commit 'refs/pull/317/head' into develop
-rw-r--r--src/compiler/scala/reflect/internal/Flags.scala2
-rw-r--r--src/compiler/scala/reflect/internal/StdNames.scala12
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala6
-rw-r--r--test/files/run/t5543.check3
-rw-r--r--test/files/run/t5543.scala26
5 files changed, 44 insertions, 5 deletions
diff --git a/src/compiler/scala/reflect/internal/Flags.scala b/src/compiler/scala/reflect/internal/Flags.scala
index c6901d1cf6..e6820cf78a 100644
--- a/src/compiler/scala/reflect/internal/Flags.scala
+++ b/src/compiler/scala/reflect/internal/Flags.scala
@@ -260,7 +260,7 @@ class Flags extends ModifierFlags {
/** When a symbol for a default getter is created, it inherits these
* flags from the method with the default. Other flags applied at creation
- * time are SYNTHETIC, DEFAULTPARAM, and possibly OVERRIDE.
+ * time are SYNTHETIC, DEFAULTPARAM, and possibly OVERRIDE, and maybe PRESUPER.
*/
final val DefaultGetterFlags = PRIVATE | PROTECTED | FINAL
diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala
index 2c2a8a1b87..5b91270de1 100644
--- a/src/compiler/scala/reflect/internal/StdNames.scala
+++ b/src/compiler/scala/reflect/internal/StdNames.scala
@@ -272,6 +272,7 @@ trait StdNames {
val BITMAP_PREFIX = "bitmap$"
val CHECK_IF_REFUTABLE_STRING = "check$ifrefutable$"
val DEFAULT_GETTER_STRING = "$default$"
+ val DEFAULT_GETTER_INIT_STRING = "$lessinit$greater" // CONSTRUCTOR.encoded, less is more
val DO_WHILE_PREFIX = "doWhile$"
val EVIDENCE_PARAM_PREFIX = "evidence$"
val EXCEPTION_RESULT_PREFIX = "exceptionResult"
@@ -413,14 +414,19 @@ trait StdNames {
name.subName(0, name.length - SETTER_SUFFIX.length)
}
+ // Nominally, name$default$N, encoded for <init>
def defaultGetterName(name: Name, pos: Int): TermName = {
- val prefix = if (isConstructorName(name)) "init" else name
+ val prefix = if (isConstructorName(name)) DEFAULT_GETTER_INIT_STRING else name
newTermName(prefix + DEFAULT_GETTER_STRING + pos)
}
+ // Nominally, name from name$default$N, CONSTRUCTOR for <init>
def defaultGetterToMethod(name: Name): TermName = {
val p = name.pos(DEFAULT_GETTER_STRING)
- if (p < name.length) name.toTermName.subName(0, p)
- else name.toTermName
+ if (p < name.length) {
+ val q = name.toTermName.subName(0, p)
+ // i.e., if (q.decoded == CONSTRUCTOR.toString) CONSTRUCTOR else q
+ if (q.toString == DEFAULT_GETTER_INIT_STRING) CONSTRUCTOR else q
+ } else name.toTermName
}
// If the name ends with $nn where nn are
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index b55406761d..d7413b48f5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -4642,7 +4642,11 @@ trait Typers extends Modes with Adaptations with Taggings {
typedValDef(vdef)
case ddef @ DefDef(_, _, _, _, _, _) =>
- newTyper(context.makeNewScope(tree, sym)).typedDefDef(ddef)
+ // flag default getters for constructors. An actual flag would be nice. See SI-5543.
+ //val flag = ddef.mods.hasDefaultFlag && ddef.mods.hasFlag(PRESUPER)
+ val flag = ddef.mods.hasDefaultFlag && sym.owner.isModuleClass &&
+ nme.defaultGetterToMethod(sym.name) == nme.CONSTRUCTOR
+ newTyper(context.makeNewScope(tree, sym)).constrTyperIf(flag).typedDefDef(ddef)
case tdef @ TypeDef(_, _, _, _) =>
typedTypeDef(tdef)
diff --git a/test/files/run/t5543.check b/test/files/run/t5543.check
new file mode 100644
index 0000000000..517038f4c7
--- /dev/null
+++ b/test/files/run/t5543.check
@@ -0,0 +1,3 @@
+Test, 7, 119
+m, 3, 19
+Test, 5, 85
diff --git a/test/files/run/t5543.scala b/test/files/run/t5543.scala
new file mode 100644
index 0000000000..651bc7f2b2
--- /dev/null
+++ b/test/files/run/t5543.scala
@@ -0,0 +1,26 @@
+
+object Test extends Function0[Int] {
+ // this and v resolve to Test.this, Test.v not A.this, A.v
+ class A(x: Function0[Int] = this)(val a: Int = v, val b: Int = v * x()) extends Function0[Int] {
+ val v = 3
+ override def toString = x.toString +", "+ a +", "+ b
+ // ordinary instance scope
+ def m(i: Int = v, y: Function0[Int] = this) = "m, "+ i +", "+ y()
+ def apply() = 19
+ }
+ object A {
+ val v = 5
+ // should happily coexist with default getters, in a happier world
+ def init(x: Function0[Int] = Test.this)(a: Int = v, b: Int = v * x()) = x.toString +", "+ a +", "+ b
+ override def toString = "A"
+ }
+ val v = 7
+ def apply() = 17
+ override def toString = "Test"
+ def main(args: Array[String]) {
+ val sut = new A()()
+ println(sut.toString)
+ println(sut.m())
+ println(A.init()())
+ }
+}