diff options
author | Paul Phillips <paulp@improving.org> | 2010-12-03 07:17:33 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-12-03 07:17:33 +0000 |
commit | 2e136c6924007f65286451f2984d286f289dc0a4 (patch) | |
tree | bc46082179bf0d261e8d8e44ea0895220995ce00 /src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala | |
parent | cc1f6bca81c9f524952b4b42b45d8e36d8df6387 (diff) | |
download | scala-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.scala | 39 |
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 |