summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2010-12-22 11:29:12 +0000
committerIulian Dragos <jaguarul@gmail.com>2010-12-22 11:29:12 +0000
commit610fdb6b5ae6e6a7b74681f0623aefb937952cfe (patch)
tree8201a1a21c6b2065b13b1cb9c026b09a5cae61ac
parentf826618f7b6dda6f03fd1a695d9600386021c8c3 (diff)
downloadscala-610fdb6b5ae6e6a7b74681f0623aefb937952cfe.tar.gz
scala-610fdb6b5ae6e6a7b74681f0623aefb937952cfe.tar.bz2
scala-610fdb6b5ae6e6a7b74681f0623aefb937952cfe.zip
Fix 'Symbol.companionModule' for the resident m...
Fix 'Symbol.companionModule' for the resident mode compiler. It was confused by having modules being translated to lazy values. The direct consequence was a crash in the build manager when looking at a constructor using a default argument (compiled separately), but only on the second run. The resident compiler may run many times over, and symbols may be reused. Therefore, a module symbol that has been translated to a lazy val by refchecks is not guaranteed to have MODULE set on the next run (even before refcheck). Flags are not part of symbol history. Instead we rely on the fact that a synthetic lazy value must have been a module. review by odersky.
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala22
-rw-r--r--test/files/buildmanager/namesdefaults/defparam-use.scala5
-rw-r--r--test/files/buildmanager/namesdefaults/defparam.scala7
-rw-r--r--test/files/buildmanager/namesdefaults/namesdefaults.check9
-rw-r--r--test/files/buildmanager/namesdefaults/namesdefaults.test3
5 files changed, 40 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index 62540527e8..543dac1665 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -1264,14 +1264,24 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
else NoSymbol
}
- /** A helper method that factors the common code used the discover a companion module of a class. If a companion
- * module exists, its symbol is returned, otherwise, `NoSymbol` is returned. The method assumes that `this`
- * symbol has already been checked to be a class (using `isClass`).
- * After refchecks nested objects get transformed to lazy vals so we filter on LAZY flag*/
+ /** A helper method that factors the common code used the discover a companion module of a class.
+ * If a companion module exists, its symbol is returned, otherwise, `NoSymbol` is returned.
+ * The method assumes that `this` symbol has already been checked to be a class (using `isClass`).
+ *
+ * After refchecks nested objects get transformed to lazy vals so we filter on LAZY flag as well.
+ * @note The resident compiler may run many times over, and symbols may be reused. Therefore, a
+ * module symbol that has been translated to a lazy val by refchecks is not guaranteed to
+ * have MODULE set on the next run (even before refcheck). Flags are not part of symbol
+ * history. Instead we rely on the fact that a synthetic lazy value must have been a
+ * module.
+ */
private final def companionModule0: Symbol = {
- val f = if (phase.refChecked && isNestedClass && !forMSIL) LAZY else MODULE
+ def isSyntheticLazy(sym: Symbol) =
+ (sym.hasAllFlags(LAZY | SYNTHETIC))
+
flatOwnerInfo.decl(name.toTermName).suchThat(
- sym => (sym hasFlag f) && (sym isCoDefinedWith this))
+ sym => (sym isCoDefinedWith this)
+ && (sym.hasFlag(MODULE) || isSyntheticLazy(sym)))
}
/** For a class: the module or case class factory wiht the same name in the same package.
diff --git a/test/files/buildmanager/namesdefaults/defparam-use.scala b/test/files/buildmanager/namesdefaults/defparam-use.scala
new file mode 100644
index 0000000000..a8a2a9f445
--- /dev/null
+++ b/test/files/buildmanager/namesdefaults/defparam-use.scala
@@ -0,0 +1,5 @@
+
+object Test extends Application {
+ val outer = new Outer
+ new outer.Inner
+}
diff --git a/test/files/buildmanager/namesdefaults/defparam.scala b/test/files/buildmanager/namesdefaults/defparam.scala
new file mode 100644
index 0000000000..d817c719ab
--- /dev/null
+++ b/test/files/buildmanager/namesdefaults/defparam.scala
@@ -0,0 +1,7 @@
+class Outer {
+
+ class Inner(val x: List[Int] = Nil)
+
+// lazy val Inner = "abc"
+}
+
diff --git a/test/files/buildmanager/namesdefaults/namesdefaults.check b/test/files/buildmanager/namesdefaults/namesdefaults.check
new file mode 100644
index 0000000000..f713d9dead
--- /dev/null
+++ b/test/files/buildmanager/namesdefaults/namesdefaults.check
@@ -0,0 +1,9 @@
+builder > defparam.scala defparam-use.scala
+compiling Set(defparam-use.scala, defparam.scala)
+Changes: Map()
+builder > defparam-use.scala
+compiling Set(defparam-use.scala)
+Changes: Map(class Test$delayedInit$body -> List(Changed(Definition(Test$delayedInit$body.<init>))[constructor Test$delayedInit$body changed from ($outer: object Test)<notype> to ($outer: object Test)Test$delayedInit$body flags: <method>], Changed(Definition(Test.delayedInit$body.<init>))[constructor delayedInit$body changed from ($outer: object Test)<notype> to ($outer: object Test)Test#delayedInit$body flags: <method>]), object Test -> List())
+builder > defparam-use.scala
+compiling Set(defparam-use.scala)
+Changes: Map(class Test$delayedInit$body -> List(Changed(Definition(Test$delayedInit$body.<init>))[constructor Test$delayedInit$body changed from ($outer: object Test)<notype> to ($outer: object Test)Test$delayedInit$body flags: <method>], Changed(Definition(Test.delayedInit$body.<init>))[constructor delayedInit$body changed from ($outer: object Test)<notype> to ($outer: object Test)Test#delayedInit$body flags: <method>]), object Test -> List())
diff --git a/test/files/buildmanager/namesdefaults/namesdefaults.test b/test/files/buildmanager/namesdefaults/namesdefaults.test
new file mode 100644
index 0000000000..84ccc36bc3
--- /dev/null
+++ b/test/files/buildmanager/namesdefaults/namesdefaults.test
@@ -0,0 +1,3 @@
+>>compile defparam.scala defparam-use.scala
+>>compile defparam-use.scala
+>>compile defparam-use.scala