Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion compiler/src/dotty/tools/dotc/tastyreflect/CoreImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ trait CoreImpl extends scala.tasty.reflect.Core {
type LambdaTypeTree = tpd.LambdaTypeTree
type Bind = tpd.Bind
}
type TypeBoundsTree = tpd.Tree
type TypeBoundsTree = tpd.TypeBoundsTree
type WildcardType = tpd.TypeTree

type TypeOrBounds = Types.Type
type NoPrefix = Types.NoPrefix.type
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ trait TypeOrBoundsTreesOpsImpl extends scala.tasty.reflect.TypeOrBoundsTreeOps w
}

object Bind extends BindExtractor {
def unapply(x: TypeTree)(implicit ctx: Context): Option[(String, TypeBoundsTree)] = x match {
def unapply(x: TypeTree)(implicit ctx: Context): Option[(String, TypeOrBoundsTree)] = x match {
case x: tpd.Bind if x.name.isTypeName => Some((x.name.toString, x.body))
case _ => None
}
Expand All @@ -141,27 +141,33 @@ trait TypeOrBoundsTreesOpsImpl extends scala.tasty.reflect.TypeOrBoundsTreeOps w

def TypeBoundsTreeDeco(bounds: TypeBoundsTree): TypeBoundsTreeAPI = new TypeBoundsTreeAPI {
def tpe(implicit ctx: Context): TypeBounds = bounds.tpe.asInstanceOf[Types.TypeBounds]
def low(implicit ctx: Context): TypeTree = bounds.asInstanceOf[tpd.TypeBoundsTree].lo
def hi(implicit ctx: Context): TypeTree = bounds.asInstanceOf[tpd.TypeBoundsTree].hi
def low(implicit ctx: Context): TypeTree = bounds.lo
def hi(implicit ctx: Context): TypeTree = bounds.hi
}

object IsTypeBoundsTree extends IsTypeBoundsTreeExtractor {
def unapply(x: TypeOrBoundsTree)(implicit ctx: Context): Option[TypeBoundsTree] = x match {
case x: tpd.TypeBoundsTree => Some(x)
case x @ Trees.TypeTree() =>
// TODO only enums generate this kind of type bounds. Is this possible without enums? If not generate tpd.TypeBoundsTree for enums instead
x.tpe match {
case tpe: Types.TypeBounds =>
Some(tpd.TypeBoundsTree(tpd.TypeTree(tpe.lo).withPos(x.pos), tpd.TypeTree(tpe.hi).withPos(x.pos)))
case _ => None
}
case _ => None
}
}

object TypeBoundsTree extends TypeBoundsTreeExtractor {
def unapply(x: TypeOrBoundsTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] = x match {
case x: tpd.TypeBoundsTree => Some(x.lo, x.hi)
case IsTypeBoundsTree(x) => Some((x.lo, x.hi))
case _ => None
}
}

object SyntheticBounds extends SyntheticBoundsExtractor {
object WildcardTypeTree extends WildcardTypeTreeExtractor {
def unapply(x: TypeOrBoundsTree)(implicit ctx: Context): Boolean = x match {
case x @ Trees.TypeTree() => x.tpe.isInstanceOf[Types.TypeBounds]
case Trees.Ident(nme.WILDCARD) => x.tpe.isInstanceOf[Types.TypeBounds]
case _ => false
}
Expand Down
5 changes: 4 additions & 1 deletion library/src/scala/tasty/reflect/Core.scala
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ package scala.tasty.reflect
* | +- Bind
* |
* +- TypeBoundsTree
* +- SyntheticBounds
* +- WildcardTypeTree
*
* +- CaseDef
* +- TypeCaseDef
Expand Down Expand Up @@ -311,6 +311,9 @@ trait Core {
/** Type tree representing a type bound written in the source */
type TypeBoundsTree <: TypeOrBoundsTree

/** Type tree representing wildcard type bounds written in the source */
type WildcardType <: TypeOrBoundsTree

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the document is not precise. Given the following code:

val a: List[_] = List(1, "String")

The underscore become TypeBoundsTree(TypeTree( | scala.this.Nothing), TypeTree( | scala.this.Any) | )

Copy link
Contributor

@liufengyun liufengyun Nov 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can give the hypothesis in #5483 a second thought.

Even if we want to report errors for type trees:

  • it's completely acceptable for end users to see the error report on the whole type tree
  • they work for type alias and infered types as well
  • In practice, I conjecture that macro authors will check types to detect errors, and then just report errors on the whole type tree instead of inspecting the components of type trees & deal with inferred and aliased types.
fooMacro[List[Int]]
              ^^^

/** Type or bounds */
type TypeOrBounds <: AnyRef

Expand Down
8 changes: 4 additions & 4 deletions library/src/scala/tasty/reflect/Printers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,8 @@ trait Printers
this += "TypeTree.Block(" ++= aliases += ", " += tpt += ")"
case TypeBoundsTree(lo, hi) =>
this += "TypeBoundsTree(" += lo += ", " += hi += ")"
case SyntheticBounds() =>
this += s"SyntheticBounds()"
case WildcardTypeTree() =>
this += s"WildcardTypeTree()"
case TypeTree.MatchType(bound, selector, cases) =>
this += "TypeTree.MatchType(" += bound += ", " += selector += ", " ++= cases += ")"
}
Expand Down Expand Up @@ -996,7 +996,7 @@ trait Printers
this += arg.name
arg.rhs match {
case IsTypeBoundsTree(rhs) => printBoundsTree(rhs)
case rhs @ SyntheticBounds() =>
case rhs @ WildcardTypeTree() =>
printTypeOrBound(rhs.tpe)
case rhs @ TypeTree.TypeLambdaTree(tparams, body) =>
def printParam(t: TypeOrBoundsTree): Unit = t match {
Expand Down Expand Up @@ -1184,7 +1184,7 @@ trait Printers
printTypeTree(lo)
this += " <: "
printTypeTree(hi)
case tpt @ SyntheticBounds() =>
case tpt @ WildcardTypeTree() =>
printTypeOrBound(tpt.tpe)
case IsTypeTree(tpt) =>
printTypeTree(tpt)
Expand Down
2 changes: 1 addition & 1 deletion library/src/scala/tasty/reflect/TreeUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ trait TreeUtils
case TypeTree.Block(typedefs, tpt) => foldTypeTree(foldTrees(x, typedefs), tpt)
case TypeTree.MatchType(boundopt, selector, cases) =>
foldTypeCaseDefs(foldTypeTree(boundopt.fold(x)(foldTypeTree(x, _)), selector), cases)
case SyntheticBounds() => x
case WildcardTypeTree() => x
case TypeBoundsTree(lo, hi) => foldTypeTree(foldTypeTree(x, lo), hi)
}

Expand Down
10 changes: 5 additions & 5 deletions library/src/scala/tasty/reflect/TypeOrBoundsTreeOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ trait TypeOrBoundsTreeOps extends Core {

val Bind: BindExtractor
abstract class BindExtractor{
def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[(String, TypeBoundsTree)]
def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[(String, TypeOrBoundsTree)]
}

val Block: BlockExtractor
Expand Down Expand Up @@ -126,10 +126,10 @@ trait TypeOrBoundsTreeOps extends Core {
def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)]
}

/** TypeBoundsTree containing an inferred type bounds */
val SyntheticBounds: SyntheticBoundsExtractor
abstract class SyntheticBoundsExtractor {
/** Matches a TypeBoundsTree containing inferred type bounds */
/** TypeBoundsTree containing wildcard type bounds */
val WildcardTypeTree: WildcardTypeTreeExtractor
abstract class WildcardTypeTreeExtractor {
/** Matches a TypeBoundsTree containing wildcard type bounds */
def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Boolean
}

Expand Down