summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-12-03 07:17:33 +0000
committerPaul Phillips <paulp@improving.org>2010-12-03 07:17:33 +0000
commit2e136c6924007f65286451f2984d286f289dc0a4 (patch)
treebc46082179bf0d261e8d8e44ea0895220995ce00 /src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
parentcc1f6bca81c9f524952b4b42b45d8e36d8df6387 (diff)
downloadscala-2e136c6924007f65286451f2984d286f289dc0a4.tar.gz
scala-2e136c6924007f65286451f2984d286f289dc0a4.tar.bz2
scala-2e136c6924007f65286451f2984d286f289dc0a4.zip
Eliminated SYNTHETICMETH flag.
meaningful name inside the pattern matcher. Created a tracker for TRANS_FLAG which could enforce the transience it promises us, but didn't turn it on. No review.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala39
1 files changed, 19 insertions, 20 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index a1f152c39c..d7a0ce0544 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -8,6 +8,7 @@ package typechecker
import symtab.Flags
import symtab.Flags._
+import scala.collection.mutable
import scala.collection.mutable.ListBuffer
/** <ul>
@@ -38,41 +39,39 @@ trait SyntheticMethods extends ast.TreeDSL {
// to override this method anyways.
protected def typer : Typer = global.typer.asInstanceOf[Typer]
+ /** In general case classes/objects are not given synthetic equals methods if some
+ * non-AnyRef implementation is inherited. However if you let a case object inherit
+ * an implementation from a case class, it creates an asymmetric equals with all the
+ * associated badness: see ticket #883. So if it sees such a thing this has happened
+ * (by virtue of the symbol being in createdMethodSymbols) it re-overrides it with
+ * reference equality.
+ */
+ private val createdMethodSymbols = new mutable.HashSet[Symbol]
+
/** Add the synthetic methods to case classes. Note that a lot of the
* complexity herein is a consequence of case classes inheriting from
* case classes, which has been deprecated as of Sep 11 2009. So when
* the opportunity for removal arises, this can be simplified.
*/
def addSyntheticMethods(templ: Template, clazz: Symbol, context: Context): Template = {
-
- val localContext = if (reporter.hasErrors) context makeSilent false else context
- val localTyper = newTyper(localContext)
+ val localContext = if (reporter.hasErrors) context makeSilent false else context
+ val localTyper = newTyper(localContext)
def hasOverridingImplementation(meth: Symbol): Boolean = {
val sym = clazz.info nonPrivateMember meth.name
- sym.alternatives exists { sym =>
- sym != meth && !(sym hasFlag DEFERRED) && !(sym hasFlag (SYNTHETIC | SYNTHETICMETH)) &&
- (clazz.thisType.memberType(sym) matches clazz.thisType.memberType(meth))
+ def isOverride(s: Symbol) = {
+ s != meth && !s.isDeferred && !s.isSynthetic && !createdMethodSymbols(s) &&
+ (clazz.thisType.memberType(s) matches clazz.thisType.memberType(meth))
}
+ sym.alternatives exists isOverride
}
def syntheticMethod(name: Name, flags: Int, tpeCons: Symbol => Type) =
newSyntheticMethod(name, flags | OVERRIDE, tpeCons)
- /** Note: at this writing this is the only place the SYNTHETICMETH is ever created.
- * The flag is commented "synthetic method, but without SYNTHETIC flag", an explanation
- * for which I now attempt to reverse engineer the motivation.
- *
- * In general case classes/objects are not given synthetic equals methods if some
- * non-AnyRef implementation is inherited. However if you let a case object inherit
- * an implementation from a case class, it creates an asymmetric equals with all the
- * associated badness: see ticket #883. So if it sees such a thing (which is marked
- * SYNTHETICMETH) it re-overrides it with reference equality.
- *
- * In other words it only exists to support (deprecated) case class inheritance.
- */
def newSyntheticMethod(name: Name, flags: Int, tpeCons: Symbol => Type) = {
- val method = clazz.newMethod(clazz.pos.focus, name) setFlag (flags | SYNTHETICMETH)
+ val method = clazz.newMethod(clazz.pos.focus, name) setFlag flags
+ createdMethodSymbols += method
method setInfo tpeCons(method)
clazz.info.decls.enter(method)
}
@@ -284,7 +283,7 @@ trait SyntheticMethods extends ast.TreeDSL {
// if there's a synthetic method in a parent case class, override its equality
// with eq (see #883)
val otherEquals = clazz.info.nonPrivateMember(Object_equals.name)
- if (otherEquals.owner != clazz && (otherEquals hasFlag SYNTHETICMETH)) ts += equalsModuleMethod
+ if (otherEquals.owner != clazz && createdMethodSymbols(otherEquals)) ts += equalsModuleMethod
}
val methods = (if (clazz.isModuleClass) objectMethods else classMethods) ++ everywhereMethods