aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-10-21 13:58:00 +0200
committerMartin Odersky <odersky@gmail.com>2016-10-31 14:44:59 +0100
commit59e83ce49fbb81f402be7d663f8f38bed0f556df (patch)
tree1fd3adae16570b5a42747b792f3dd651d5e2fddc /src/dotty/tools/dotc/transform
parent08658cb20fee008217966830c51a0ff56ee1ae72 (diff)
downloaddotty-59e83ce49fbb81f402be7d663f8f38bed0f556df.tar.gz
dotty-59e83ce49fbb81f402be7d663f8f38bed0f556df.tar.bz2
dotty-59e83ce49fbb81f402be7d663f8f38bed0f556df.zip
Don't convert to TypeTrees before pickling
If we want to pickle types with positions we should not converyt to TypeTrees before pickling. Instead, type trees are now converted to TypeTrees in FirstTransform.
Diffstat (limited to 'src/dotty/tools/dotc/transform')
-rw-r--r--src/dotty/tools/dotc/transform/FirstTransform.scala10
-rw-r--r--src/dotty/tools/dotc/transform/PostTyper.scala47
2 files changed, 39 insertions, 18 deletions
diff --git a/src/dotty/tools/dotc/transform/FirstTransform.scala b/src/dotty/tools/dotc/transform/FirstTransform.scala
index 74dc9b9d6..adadf3e76 100644
--- a/src/dotty/tools/dotc/transform/FirstTransform.scala
+++ b/src/dotty/tools/dotc/transform/FirstTransform.scala
@@ -146,7 +146,7 @@ class FirstTransform extends MiniPhaseTransform with InfoTransformer with Annota
override def transformTemplate(impl: Template)(implicit ctx: Context, info: TransformerInfo): Tree = {
cpy.Template(impl)(self = EmptyValDef)
}
-
+
override def transformDefDef(ddef: DefDef)(implicit ctx: Context, info: TransformerInfo) = {
if (ddef.symbol.hasAnnotation(defn.NativeAnnot)) {
ddef.symbol.resetFlag(Deferred)
@@ -162,9 +162,15 @@ class FirstTransform extends MiniPhaseTransform with InfoTransformer with Annota
override def transformOther(tree: Tree)(implicit ctx: Context, info: TransformerInfo) = tree match {
case tree: Import => EmptyTree
case tree: NamedArg => transform(tree.arg)
- case tree => tree
+ case tree => if (tree.isType) TypeTree(tree.tpe).withPos(tree.pos) else tree
}
+ override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo) =
+ if (tree.isType) TypeTree(tree.tpe).withPos(tree.pos) else tree
+
+ override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) =
+ if (tree.isType) TypeTree(tree.tpe).withPos(tree.pos) else tree
+
// invariants: all modules have companion objects
// all types are TypeTrees
// all this types are explicit
diff --git a/src/dotty/tools/dotc/transform/PostTyper.scala b/src/dotty/tools/dotc/transform/PostTyper.scala
index e4447509b..650bc4968 100644
--- a/src/dotty/tools/dotc/transform/PostTyper.scala
+++ b/src/dotty/tools/dotc/transform/PostTyper.scala
@@ -76,8 +76,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
// TODO fill in
}
- /** Check bounds of AppliedTypeTrees and TypeApplys.
- * Replace type trees with TypeTree nodes.
+ /** Check bounds of AppliedTypeTrees.
* Replace constant expressions with Literal nodes.
* Note: Demanding idempotency instead of purity in literalize is strictly speaking too loose.
* Example
@@ -105,18 +104,15 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
* Revisit this issue once we have implemented `inline`. Then we can demand
* purity of the prefix unless the selection goes to an inline val.
*/
- private def normalizeTree(tree: Tree)(implicit ctx: Context): Tree = tree match {
- case _: TypeTree | _: TypeApply => tree
- case _ =>
- if (tree.isType) {
- Checking.typeChecker.traverse(tree)
- TypeTree(tree.tpe).withPos(tree.pos)
- }
- else tree.tpe.widenTermRefExpr match {
- case ConstantType(value) if isIdempotentExpr(tree) => Literal(value)
- case _ => tree
- }
- }
+ private def normalizeTree(tree: Tree)(implicit ctx: Context): Tree =
+ if (tree.isType) {
+ Checking.typeCheck(tree)
+ tree
+ }
+ else tree.tpe.widenTermRefExpr match {
+ case ConstantType(value) if isIdempotentExpr(tree) => Literal(value)
+ case _ => tree
+ }
/** If the type of `tree` is a TermRefWithSignature with an underdefined
* signature, narrow the type by re-computing the signature (which should
@@ -203,12 +199,12 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
override def transform(tree: Tree)(implicit ctx: Context): Tree =
try normalizeTree(tree) match {
- case tree: Ident =>
+ case tree: Ident if !tree.isType =>
tree.tpe match {
case tpe: ThisType => This(tpe.cls).withPos(tree.pos)
case _ => paramFwd.adaptRef(fixSignature(tree))
}
- case tree: Select =>
+ case tree: Select if !tree.isType =>
transformSelect(paramFwd.adaptRef(fixSignature(tree)), Nil)
case tree: Super =>
if (ctx.owner.enclosingMethod.isInlineMethod)
@@ -284,6 +280,25 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
super.transform(tree)
case tree @ Annotated(annotated, annot) =>
cpy.Annotated(tree)(transform(annotated), transformAnnot(annot))
+ case AppliedTypeTree(tycon, args) =>
+ // If `args` is a list of named arguments, return corresponding type parameters,
+ // otherwise return type parameters unchanged
+ val tparams = tycon.tpe.typeParams
+ def argNamed(tparam: TypeParamInfo) = args.find {
+ case NamedArg(name, _) => name == tparam.paramName
+ case _ => false
+ }.getOrElse(TypeTree(tparam.paramRef))
+ val orderedArgs = if (hasNamedArg(args)) tparams.map(argNamed) else args
+ val bounds = tparams.map(_.paramBoundsAsSeenFrom(tycon.tpe))
+ def instantiate(bound: Type, args: List[Type]) =
+ bound.LambdaAbstract(tparams).appliedTo(args)
+ Checking.checkBounds(orderedArgs, bounds, instantiate)
+
+ def checkValidIfHKApply(implicit ctx: Context): Unit =
+ Checking.checkWildcardHKApply(tycon.tpe.appliedTo(args.map(_.tpe)), tree.pos)
+ checkValidIfHKApply(ctx.addMode(Mode.AllowLambdaWildcardApply))
+ super.transform(tree)
+
case tree: TypeTree =>
tree.withType(
tree.tpe match {