diff options
author | Martin Odersky <odersky@gmail.com> | 2016-10-21 13:58:00 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-10-31 14:44:59 +0100 |
commit | 59e83ce49fbb81f402be7d663f8f38bed0f556df (patch) | |
tree | 1fd3adae16570b5a42747b792f3dd651d5e2fddc /src/dotty/tools/dotc/transform | |
parent | 08658cb20fee008217966830c51a0ff56ee1ae72 (diff) | |
download | dotty-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.scala | 10 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/PostTyper.scala | 47 |
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 { |