@@ -12,7 +12,7 @@ import Denotations._, Decorators._, DenotTransformers._
12
12
import collection .mutable
13
13
import util .{Property , SourceFile , NoSource }
14
14
import typer .ErrorReporting ._
15
- import NameKinds .TempResultName
15
+ import NameKinds .{ TempResultName , OuterSelectName }
16
16
17
17
import scala .annotation .tailrec
18
18
import scala .io .Codec
@@ -171,6 +171,13 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
171
171
def SyntheticValDef (name : TermName , rhs : Tree )(implicit ctx : Context ): ValDef =
172
172
ValDef (ctx.newSymbol(ctx.owner, name, Synthetic , rhs.tpe.widen, coord = rhs.pos), rhs)
173
173
174
+ def DefDef (sym : TermSymbol , tparams : List [TypeSymbol ], vparamss : List [List [TermSymbol ]],
175
+ resultType : Type , rhs : Tree )(implicit ctx : Context ): DefDef =
176
+ ta.assignType(
177
+ untpd.DefDef (sym.name, tparams map TypeDef , vparamss.nestedMap(ValDef (_)),
178
+ TypeTree (resultType), rhs),
179
+ sym)
180
+
174
181
def DefDef (sym : TermSymbol , rhs : Tree = EmptyTree )(implicit ctx : Context ): DefDef =
175
182
ta.assignType(DefDef (sym, Function .const(rhs) _), sym)
176
183
@@ -199,14 +206,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
199
206
val (vparamss, rtp) = valueParamss(mtp)
200
207
val targs = tparams map (_.typeRef)
201
208
val argss = vparamss.nestedMap(vparam => Ident (vparam.termRef))
202
- ta.assignType(
203
- untpd.DefDef (
204
- sym.name,
205
- tparams map TypeDef ,
206
- vparamss.nestedMap(ValDef (_)),
207
- TypeTree (rtp),
208
- rhsFn(targs)(argss)),
209
- sym)
209
+ DefDef (sym, tparams, vparamss, rtp, rhsFn(targs)(argss))
210
210
}
211
211
212
212
def TypeDef (sym : TypeSymbol )(implicit ctx : Context ): TypeDef =
@@ -682,6 +682,12 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
682
682
def select (name : Name )(implicit ctx : Context ): Select =
683
683
Select (tree, name)
684
684
685
+ /** A select node with the given selector name such that the designated
686
+ * member satisfies predicate `p`. Useful for disambiguating overloaded members.
687
+ */
688
+ def select (name : Name , p : Symbol => Boolean )(implicit ctx : Context ): Select =
689
+ select(tree.tpe.member(name).suchThat(p).symbol)
690
+
685
691
/** A select node with the given type */
686
692
def select (tp : NamedType )(implicit ctx : Context ): Select =
687
693
untpd.Select (tree, tp.name).withType(tp)
@@ -751,9 +757,20 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
751
757
def ensureApplied (implicit ctx : Context ): Tree =
752
758
if (tree.tpe.widen.isParameterless) tree else tree.appliedToNone
753
759
754
- /** `tree.isInstanceOf[tp]` */
755
- def isInstance (tp : Type )(implicit ctx : Context ): Tree =
756
- tree.select(defn.Any_isInstanceOf ).appliedToType(tp)
760
+ /** `tree == that` */
761
+ def equal (that : Tree )(implicit ctx : Context ) =
762
+ applyOverloaded(tree, nme.EQ , that :: Nil , Nil , defn.BooleanType )
763
+
764
+ /** `tree.isInstanceOf[tp]`, with special treatment of singleton types */
765
+ def isInstance (tp : Type )(implicit ctx : Context ): Tree = tp match {
766
+ case tp : SingletonType =>
767
+ if (tp.widen.derivesFrom(defn.ObjectClass ))
768
+ tree.ensureConforms(defn.ObjectType ).select(defn.Object_eq ).appliedTo(singleton(tp))
769
+ else
770
+ singleton(tp).equal(tree)
771
+ case _ =>
772
+ tree.select(defn.Any_isInstanceOf ).appliedToType(tp)
773
+ }
757
774
758
775
/** tree.asInstanceOf[`tp`] */
759
776
def asInstance (tp : Type )(implicit ctx : Context ): Tree = {
@@ -771,7 +788,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
771
788
else Erasure .Boxing .adaptToType(tree, tp)
772
789
773
790
/** `tree ne null` (might need a cast to be type correct) */
774
- def testNotNull (implicit ctx : Context ): Tree =
791
+ def testNotNull (implicit ctx : Context ): Tree =
775
792
tree.ensureConforms(defn.ObjectType )
776
793
.select(defn.Object_ne ).appliedTo(Literal (Constant (null )))
777
794
@@ -805,6 +822,13 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
805
822
}
806
823
else Assign (tree, rhs)
807
824
825
+ /** A synthetic select with that will be turned into an outer path by ExplicitOuter.
826
+ * @param levels How many outer levels to select
827
+ * @param tp The type of the destination of the outer path.
828
+ */
829
+ def outerSelect (levels : Int , tp : Type )(implicit ctx : Context ): Tree =
830
+ untpd.Select (tree, OuterSelectName (EmptyTermName , levels)).withType(tp)
831
+
808
832
// --- Higher order traversal methods -------------------------------
809
833
810
834
/** Apply `f` to each subtree of this tree */
0 commit comments