summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala54
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala4
-rw-r--r--test/pending/run/implicit-classes.scala17
3 files changed, 66 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
index f32ad9293c..5287fad3bb 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -169,6 +169,16 @@ trait MethodSynthesis {
self: Namer =>
import NamerErrorGen._
+
+ /** TODO - synthesize method.
+ */
+ def enterImplicitClass(tree: ClassDef) {
+ /** e.g.
+ val ClassDef(mods, name, tparams, impl) = tree
+ val converter = ImplicitClassConverter(tree).createAndEnterSymbol()
+ ...
+ */
+ }
def enterGetterSetter(tree: ValDef) {
val ValDef(mods, name, _, _) = tree
@@ -230,14 +240,33 @@ trait MethodSynthesis {
}
trait Derived {
+ /** The tree from which we are deriving a synthetic member. */
+ def tree: Tree
def name: TermName
def flagsMask: Long
def flagsExtra: Long
+
+ /** The tree, symbol, and type completer for the synthetic member. */
def completer(sym: Symbol): Type
+ def derivedSym: Symbol
+ def derivedTree: Tree
}
- trait DerivedFromValDef extends Derived {
- /** The declaration from which we are deriving.
- */
+
+ trait DerivedFromMemberDef extends Derived {
+ def tree: MemberDef
+
+ // Final methods to make the rest easier to reason about.
+ final def mods = tree.mods
+ final def basisSym = tree.symbol
+ final def enclClass = basisSym.enclClass
+ final def derivedFlags: Long = basisSym.flags & flagsMask | flagsExtra
+ }
+
+ trait DerivedFromClassDef extends DerivedFromMemberDef {
+ def tree: ClassDef
+ }
+
+ trait DerivedFromValDef extends DerivedFromMemberDef {
def tree: ValDef
/** Which meta-annotation is associated with this kind of entity.
@@ -245,14 +274,8 @@ trait MethodSynthesis {
*/
def category: Symbol
- // Final methods to make the rest easier to reason about.
- final def mods = tree.mods
- final def basisSym = tree.symbol
- final def enclClass = basisSym.enclClass
-
final def completer(sym: Symbol) = namerOf(sym).accessorTypeCompleter(tree, isSetter)
final def fieldSelection = Select(This(enclClass), basisSym)
- final def derivedFlags: Long = basisSym.flags & flagsMask | flagsExtra
final def derivedMods: Modifiers = mods & flagsMask | flagsExtra mapAnnotations (_ => Nil)
def derivedSym: Symbol = tree.symbol
@@ -312,6 +335,19 @@ trait MethodSynthesis {
private def setterDef = DefDef(derivedSym, setterRhs)
override def derivedTree: Tree = if (setterParam == NoSymbol) EmptyTree else setterDef
}
+
+ /** A synthetic method which performs the implicit conversion implied by
+ * the declaration of an implicit class. Yet to be written.
+ */
+ case class ImplicitClassConverter(tree: ClassDef) extends DerivedFromClassDef {
+ def completer(sym: Symbol): Type = ???
+ def derivedSym: Symbol = ???
+ def derivedTree: DefDef = ???
+ def flagsExtra: Long = ???
+ def flagsMask: Long = ???
+ def name: TermName = ???
+ }
+
case class Getter(tree: ValDef) extends DerivedGetter {
def name = tree.name
def category = GetterTargetClass
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index c5fb13a5a9..6b27c27652 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -665,6 +665,10 @@ trait Namers extends MethodSynthesis {
"If possible, define " + tree.symbol + " in " + owner.skipPackageObject + " instead."
)
}
+
+ // Suggested location only.
+ if (mods.isImplicit)
+ enterImplicitClass(tree)
}
// this logic is needed in case typer was interrupted half
diff --git a/test/pending/run/implicit-classes.scala b/test/pending/run/implicit-classes.scala
new file mode 100644
index 0000000000..02b74de2b0
--- /dev/null
+++ b/test/pending/run/implicit-classes.scala
@@ -0,0 +1,17 @@
+object O {
+ implicit class C(s: String) {
+ def twice = s + s
+ }
+}
+
+/**
+//
+// We'd like to augment object O in Namers so that it also has an implicit method
+object O {
+ implicit class C(s: String) {
+ def twice = s + s
+ }
+ implicit def C(s: String): C = new C(s)
+}
+
+**/