summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-10-22 21:09:11 +0000
committerPaul Phillips <paulp@improving.org>2011-10-22 21:09:11 +0000
commit290f687fb6ab91b6aef62d871036ddc3829f12b4 (patch)
treea55663699fa69315ba4e640252cc6694cbd805d6 /src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
parent0c97d8c73fdf4e1dd33ee98ea2e14bc51388bb5f (diff)
downloadscala-290f687fb6ab91b6aef62d871036ddc3829f12b4.tar.gz
scala-290f687fb6ab91b6aef62d871036ddc3829f12b4.tar.bz2
scala-290f687fb6ab91b6aef62d871036ddc3829f12b4.zip
Overhaul of Namers continues.
Starting to see a glimmer of the other side now. I nudged a few things into more sensible places. No review.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
new file mode 100644
index 0000000000..882b43bf2b
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -0,0 +1,106 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Paul Phillips
+ */
+package scala.tools.nsc
+package typechecker
+
+import symtab.Flags._
+
+object listutil {
+ def mexists[T](xss: List[List[T]])(p: T => Boolean) =
+ xss exists (_ exists p)
+ def mmap[T, U](xss: List[List[T]])(f: T => U) =
+ xss map (_ map f)
+ def mforeach[T](xss: List[List[T]])(f: T => Unit) =
+ xss foreach (_ foreach f)
+ def mfind[T](xss: List[List[T]])(p: T => Boolean): Option[T] = {
+ for (xs <- xss; x <- xs)
+ if (p(x)) return Some(x)
+ None
+ }
+ def mfilter[T](xss: List[List[T]])(p: T => Boolean) =
+ for (xs <- xss; x <- xs; if p(x)) yield x
+}
+
+/** Logic related to method synthesis which involves cooperation between
+ * Namer and Typer.
+ */
+trait MethodSynthesis {
+ self: Analyzer =>
+
+ import global._
+ import definitions._
+
+ trait MethodSynth {
+ self: Namer =>
+
+ private def createAccessorSymbol(tree: ValDef, name: Name, mask: Long): TermSymbol = (
+ context.owner.newMethod(tree.pos.focus, name) setFlag tree.mods.flags & mask
+ )
+
+ // TODO
+ object Derived {
+ def apply(tree: Tree): Derived = tree match {
+ case vd @ ValDef(mods, name, _, _) =>
+ if (mods hasAnnotationNamed tpnme.BeanPropertyAnnot)
+ BeanGetter(vd)
+ else if (mods hasAnnotationNamed tpnme.BooleanBeanPropertyAnnot)
+ BooleanBeanGetter(vd)
+ else
+ NoDerived
+ case _ => NoDerived
+ }
+ }
+ object NoDerived extends Derived {
+ def name = nme.NO_NAME
+ def flagsMask = 0L
+ def flagsExtra = 0L
+ def completer(sym: Symbol) = NoType
+ }
+ trait Derived {
+ def name: TermName
+ def flagsMask: Long
+ def flagsExtra: Long
+ def completer(sym: Symbol): Type
+ }
+ trait DerivedAccessor extends Derived {
+ def tree: ValDef
+ def isSetter: Boolean
+ def completer(sym: Symbol) = namerOf(sym).accessorTypeCompleter(tree, isSetter)
+ def enterAccessor(): Symbol = {
+ val sym = createAccessorSymbol(tree, name, flagsMask) setFlag flagsExtra
+ setPrivateWithin(tree, sym)
+ enterInScope(sym)
+ sym setInfo completer(sym)
+ }
+ }
+ case class Getter(tree: ValDef) extends DerivedAccessor {
+ def name = tree.name
+ def isSetter = false
+ def flagsMask = GetterFlags
+ def flagsExtra = ACCESSOR | ( if (tree.mods.isMutable) 0 else STABLE )
+ }
+ case class Setter(tree: ValDef) extends DerivedAccessor {
+ def name = nme.getterToSetter(tree.name)
+ def isSetter = true
+ def flagsMask = SetterFlags
+ def flagsExtra = ACCESSOR
+ }
+ case class Field(tree: ValDef) extends DerivedAccessor {
+ def name = nme.getterToLocal(tree.name)
+ def isSetter = false
+ def flagsMask = FieldFlags
+ def flagsExtra = PrivateLocal
+ }
+
+ sealed abstract class BeanAccessor(bean: String, val isSetter: Boolean) extends DerivedAccessor {
+ def name = bean + tree.name.toString.capitalize
+ def flagsMask = BeanPropertyFlags
+ def flagsExtra = 0
+ }
+ case class BooleanBeanGetter(tree: ValDef) extends BeanAccessor("is", false)
+ case class BeanGetter(tree: ValDef) extends BeanAccessor("get", false)
+ case class BeanSetter(tree: ValDef) extends BeanAccessor("set", true)
+ }
+} \ No newline at end of file