diff options
author | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2014-11-04 15:19:41 +0100 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2014-11-22 20:10:22 +0100 |
commit | 32954ba55955f4335bb34007269e3d405faa1780 (patch) | |
tree | 4410a4a406fd5dceb97a74b3a1df78bc0d4d8c5c /src | |
parent | cc8ca00fc1718bcbb49e3c61f3c0682eac2a7e7c (diff) | |
download | dotty-32954ba55955f4335bb34007269e3d405faa1780.tar.gz dotty-32954ba55955f4335bb34007269e3d405faa1780.tar.bz2 dotty-32954ba55955f4335bb34007269e3d405faa1780.zip |
Extracting ApplyOverloaded to be reused in UnPickler and ClassfileParser
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/ast/tpd.scala | 18 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Annotations.scala | 15 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/ClassfileParser.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/UnPickler.scala | 18 |
4 files changed, 37 insertions, 16 deletions
diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala index c735f079c..9bf19dc5c 100644 --- a/src/dotty/tools/dotc/ast/tpd.scala +++ b/src/dotty/tools/dotc/ast/tpd.scala @@ -2,6 +2,7 @@ package dotty.tools package dotc package ast +import dotty.tools.dotc.typer.ProtoTypes.FunProtoTyped import transform.SymUtils._ import core._ import util.Positions._, Types._, Contexts._, Constants._, Names._, Flags._ @@ -677,6 +678,23 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { Throw(New(defn.ClassCastExceptionClass.typeRef, Nil)) withPos tree.pos } } + + def applyOverloaded(receiver: Tree, method: TermName, args: List[Tree], targs: List[Type], expectedType: Type)(implicit ctx: Context): Tree = { + val typer = ctx.typer + val proto = new FunProtoTyped(args, expectedType, typer) + val alts = receiver.tpe.member(method).alternatives.map(_.termRef) + + val alternatives = ctx.typer.resolveOverloaded(alts, proto, Nil) + assert(alternatives.size == 1) // this is parsed from bytecode tree. there's nothing user can do about it + + val selected = alternatives.head + val fun = receiver + .select(TermRef.withSig(receiver.tpe.normalizedPrefix, selected.termSymbol.asTerm)) + .appliedToTypes(targs) + val apply = untpd.Apply(fun, args) + + new typer.ApplyToTyped(apply, fun, selected, args, expectedType).result.asInstanceOf[Tree] // needed to handle varargs + } @tailrec def sameTypes(trees: List[tpd.Tree], trees1: List[tpd.Tree]): Boolean = { diff --git a/src/dotty/tools/dotc/core/Annotations.scala b/src/dotty/tools/dotc/core/Annotations.scala index 92b28a193..814b6db49 100644 --- a/src/dotty/tools/dotc/core/Annotations.scala +++ b/src/dotty/tools/dotc/core/Annotations.scala @@ -3,6 +3,9 @@ package core import Symbols._, Types._, util.Positions._, Contexts._, Constants._, ast.tpd._ import config.ScalaVersion +import StdNames._ +import dotty.tools.dotc.ast.{tpd, untpd} +import dotty.tools.dotc.typer.ProtoTypes.FunProtoTyped object Annotations { @@ -61,12 +64,24 @@ object Annotations { def apply(atp: Type, args: List[Tree])(implicit ctx: Context): Annotation = apply(New(atp, args)) + private def resolveConstructor(atp: Type, args:List[Tree])(implicit ctx: Context): Tree = { + val targs = atp.argTypes + tpd.applyOverloaded(New(atp withoutArgs targs), nme.CONSTRUCTOR, args, targs, atp) + } + + def applyResolve(atp: Type, args: List[Tree])(implicit ctx: Context): Annotation = { + apply(resolveConstructor(atp, args)) + } + def deferred(sym: Symbol, treeFn: Context => Tree)(implicit ctx: Context): Annotation = new LazyAnnotation(sym)(treeFn) def deferred(atp: Type, args: List[Tree])(implicit ctx: Context): Annotation = deferred(atp.classSymbol, implicit ctx => New(atp, args)) + def deferredResolve(atp: Type, args: List[Tree])(implicit ctx: Context): Annotation = + deferred(atp.classSymbol, implicit ctx => resolveConstructor(atp, args)) + def makeAlias(sym: TermSymbol)(implicit ctx: Context) = apply(defn.AliasAnnot, List( ref(TermRef.withSigAndDenot(sym.owner.thisType, sym.name, sym.signature, sym)))) diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala index fb5a6309b..8bf84e1a9 100644 --- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala +++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala @@ -444,7 +444,7 @@ class ClassfileParser( } } if (hasError || skip) None - else Some(Annotation.deferred(attrType, argbuf.toList)) + else Some(Annotation.deferredResolve(attrType, argbuf.toList)) } catch { case f: FatalError => throw f // don't eat fatal errors, they mean a class was not found case ex: Throwable => diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala index c503f447b..728048700 100644 --- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala +++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala @@ -832,22 +832,10 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: t.toList } // println(atp) - val typer = ctx.typer - val proto = new FunProtoTyped(args, atp, typer) - val alts = atp.member(nme.CONSTRUCTOR).alternatives.map(_.termRef) - - val constructors = ctx.typer.resolveOverloaded(alts, proto, Nil) - assert(constructors.size == 1) // this is parsed from bytecode tree. there's nothing user can do about it - - val constr = constructors.head val targs = atp.argTypes - val fun = tpd.New(atp withoutArgs targs) - .select(TermRef.withSig(atp.normalizedPrefix, constr.termSymbol.asTerm)) - .appliedToTypes(targs) - val apply = untpd.Apply(fun, args) - new typer.ApplyToTyped(apply, fun, constr, args, atp).result.asInstanceOf[tpd.Tree] // needed to handle varargs - // Dotty deviation, for scalac the last cast wouldn't be required - } + + tpd.applyOverloaded(tpd.New(atp withoutArgs targs), nme.CONSTRUCTOR, args, targs, atp) +} /** Read an annotation and as a side effect store it into * the symbol it requests. Called at top-level, for all |