aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core
diff options
context:
space:
mode:
authorDmitry Petrashko <dark@d-d.me>2014-11-24 13:51:44 +0100
committerDmitry Petrashko <dark@d-d.me>2014-11-24 13:51:44 +0100
commit779afd2f65f967ec5af1ac5ec7464ad5851852ad (patch)
treeaf6d2ff5b81ee10e7a427ec7b36a2ac5639981a3 /src/dotty/tools/dotc/core
parent33feb9dea9db0695f510654348455133707e0740 (diff)
parent859a7fe21d4e2b9a2f336bc38815b21367a2993b (diff)
downloaddotty-779afd2f65f967ec5af1ac5ec7464ad5851852ad.tar.gz
dotty-779afd2f65f967ec5af1ac5ec7464ad5851852ad.tar.bz2
dotty-779afd2f65f967ec5af1ac5ec7464ad5851852ad.zip
Merge pull request #213 from dotty-staging/javaparser
Javaparser & ElimRepeated fixes & Annotation-fixes
Diffstat (limited to 'src/dotty/tools/dotc/core')
-rw-r--r--src/dotty/tools/dotc/core/Annotations.scala15
-rw-r--r--src/dotty/tools/dotc/core/Flags.scala11
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala5
-rw-r--r--src/dotty/tools/dotc/core/Types.scala17
-rw-r--r--src/dotty/tools/dotc/core/pickling/ClassfileParser.scala44
-rw-r--r--src/dotty/tools/dotc/core/pickling/PickleBuffer.scala3
-rw-r--r--src/dotty/tools/dotc/core/pickling/UnPickler.scala32
7 files changed, 107 insertions, 20 deletions
diff --git a/src/dotty/tools/dotc/core/Annotations.scala b/src/dotty/tools/dotc/core/Annotations.scala
index 92b28a193..79aa058ef 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, isAnnotConstructor = true)
+ }
+
+ 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/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala
index db969767b..0e86a2936 100644
--- a/src/dotty/tools/dotc/core/Flags.scala
+++ b/src/dotty/tools/dotc/core/Flags.scala
@@ -318,7 +318,7 @@ object Flags {
/** An unpickled Scala 2.x class */
final val Scala2x = typeFlag(26, "<scala-2.x>")
- /** A method that has default params */ // TODO: drop
+ /** A method that has default params */
final val DefaultParameterized = termFlag(27, "<defaultparam>")
/** Symbol is initialized to the default value, e.g. var x: T = _ */
@@ -356,6 +356,12 @@ object Flags {
/** Symbol is a Java-style varargs method */
final val JavaVarargs = termFlag(37, "<varargs>")
+ /** Symbol is a Java default method */
+ final val DefaultMethod = termFlag(38, "<defaultmethod>")
+
+ /** Symbol is a Java enum */
+ final val Enum = commonFlag(40, "<enum>")
+
// Flags following this one are not pickled
/** Symbol always defines a fresh named type */
@@ -547,6 +553,9 @@ object Flags {
/** A Java interface, potentially with default methods */
final val JavaTrait = allOf(JavaDefined, Trait, NoInits)
+
+ /** A Java interface */
+ final val JavaInterface = allOf(JavaDefined, Trait)
/** A Java companion object */
final val JavaModule = allOf(JavaDefined, Module)
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala
index bf756facf..3beb680d9 100644
--- a/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -284,7 +284,10 @@ class TypeApplications(val self: Type) extends AnyVal {
* or, if isJava is true, Array type, else the type itself.
*/
def underlyingIfRepeated(isJava: Boolean)(implicit ctx: Context): Type =
- if (self.isRepeatedParam) translateParameterized(defn.RepeatedParamClass, defn.SeqClass)
+ if (self.isRepeatedParam) {
+ val seqClass = if(isJava) defn.ArrayClass else defn.SeqClass
+ translateParameterized(defn.RepeatedParamClass, seqClass)
+ }
else self
/** If this is an encoding of a (partially) applied type, return its arguments,
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index aa8036fc5..2997e9e77 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -35,6 +35,8 @@ object Types {
private var recCount = 0 // used temporarily for debugging. TODO: remove
+ private var nextId = 0
+
/** The class of types.
* The principal subclasses and sub-objects are as follows:
*
@@ -70,6 +72,13 @@ object Types {
// ----- Tests -----------------------------------------------------
+ val uniqId = {
+ nextId = nextId + 1
+// if(nextId == 19555)
+// println("foo")
+ nextId
+ }
+
/** Is this type different from NoType? */
def exists: Boolean = true
@@ -1965,7 +1974,9 @@ object Types {
def fromSymbols(params: List[Symbol], resultType: Type)(implicit ctx: Context) = {
def paramInfo(param: Symbol): Type = param.info match {
case AnnotatedType(annot, tp) if annot matches defn.RepeatedAnnot =>
- tp.translateParameterized(defn.SeqClass, defn.RepeatedParamClass)
+ val typeSym = param.info.typeSymbol.asClass
+ assert(typeSym == defn.SeqClass || typeSym == defn.ArrayClass)
+ tp.translateParameterized(typeSym, defn.RepeatedParamClass)
case tp =>
tp
}
@@ -2024,9 +2035,9 @@ object Types {
def derivedPolyType(paramNames: List[TypeName], paramBounds: List[TypeBounds], restpe: Type)(implicit ctx: Context) =
if ((paramNames eq this.paramNames) && (paramBounds eq this.paramBounds) && (restpe eq this.resultType)) this
- else copy(paramNames, paramBounds, restpe)
+ else duplicate(paramNames, paramBounds, restpe)
- def copy(paramNames: List[TypeName], paramBounds: List[TypeBounds], restpe: Type)(implicit ctx: Context) =
+ def duplicate(paramNames: List[TypeName] = this.paramNames, paramBounds: List[TypeBounds] = this.paramBounds, restpe: Type)(implicit ctx: Context) =
PolyType(paramNames)(
x => paramBounds mapConserve (_.subst(this, x).bounds),
x => restpe.subst(this, x))
diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
index 8dd9314ee..f92573d22 100644
--- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
+++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
@@ -128,6 +128,7 @@ class ClassfileParser(
for (i <- 0 until in.nextChar) parseMember(method = false)
for (i <- 0 until in.nextChar) parseMember(method = true)
classInfo = parseAttributes(classRoot.symbol, classInfo)
+ if (isAnnotation) addAnnotationConstructor(classInfo)
setClassInfo(classRoot, classInfo)
setClassInfo(moduleRoot, staticInfo)
}
@@ -421,7 +422,7 @@ class ClassfileParser(
case None => hasError = true
}
if (hasError) None
- else if (skip) None else Some(SeqLiteral(arr.toList))
+ else if (skip) None else Some(JavaSeqLiteral(arr.toList))
case ANNOTATION_TAG =>
parseAnnotation(index, skip) map (_.tree)
}
@@ -443,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 =>
@@ -551,6 +552,45 @@ class ClassfileParser(
newType
}
+ /** Add a synthetic constructor and potentially also default getters which
+ * reflects the fields of the annotation with given `classInfo`.
+ * Annotations in Scala are assumed to get all their arguments as constructor
+ * parameters. For Java annotations we need to fake it by making up the constructor.
+ * Note that default getters have type Nothing. That's OK because we need
+ * them only to signal that the corresponding parameter is optional.
+ */
+ def addAnnotationConstructor(classInfo: Type, tparams: List[Symbol] = Nil)(implicit ctx: Context): Unit = {
+ def addDefaultGetter(attr: Symbol, n: Int) =
+ ctx.newSymbol(
+ owner = moduleRoot.symbol,
+ name = nme.CONSTRUCTOR.defaultGetterName(n),
+ flags = attr.flags & Flags.AccessFlags,
+ info = defn.NothingType).entered
+
+ classInfo match {
+ case classInfo @ TempPolyType(tparams, restpe) if tparams.isEmpty =>
+ addAnnotationConstructor(restpe, tparams)
+ case classInfo: TempClassInfoType =>
+ val attrs = classInfo.decls.toList.filter(_.isTerm)
+ val targs = tparams.map(_.typeRef)
+ val methType = MethodType(
+ attrs.map(_.name.asTermName),
+ attrs.map(_.info.resultType),
+ classRoot.typeRef.appliedTo(targs))
+ val constr = ctx.newSymbol(
+ owner = classRoot.symbol,
+ name = nme.CONSTRUCTOR,
+ flags = Flags.Synthetic,
+ info = if (tparams.isEmpty) methType else TempPolyType(tparams, methType)
+ ).entered
+ for ((attr, i) <- attrs.zipWithIndex)
+ if (attr.hasAnnotation(defn.AnnotationDefaultAnnot)) {
+ constr.setFlag(Flags.HasDefaultParams)
+ addDefaultGetter(attr, i)
+ }
+ }
+ }
+
/** Enter own inner classes in the right scope. It needs the scopes to be set up,
* and implicitly current class' superclasses.
*/
diff --git a/src/dotty/tools/dotc/core/pickling/PickleBuffer.scala b/src/dotty/tools/dotc/core/pickling/PickleBuffer.scala
index 9f8d4fc2d..c16b794b7 100644
--- a/src/dotty/tools/dotc/core/pickling/PickleBuffer.scala
+++ b/src/dotty/tools/dotc/core/pickling/PickleBuffer.scala
@@ -251,7 +251,8 @@ object PickleBuffer {
SPECIALIZED -> Specialized,
DEFAULTINIT -> DefaultInit,
VBRIDGE -> VBridge,
- VARARGS -> JavaVarargs)
+ VARARGS -> JavaVarargs,
+ ENUM -> Enum)
// generate initial maps from Scala flags to Dotty flags
val termMap, typeMap = new Array[Long](64)
diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
index 60000441c..728048700 100644
--- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala
+++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
@@ -9,8 +9,9 @@ import java.lang.Double.longBitsToDouble
import Contexts._, Symbols._, Types._, Scopes._, SymDenotations._, Names._, NameOps._
import StdNames._, Denotations._, NameOps._, Flags._, Constants._, Annotations._
+import dotty.tools.dotc.typer.ProtoTypes.{FunProtoTyped, FunProto}
import util.Positions._
-import ast.Trees, ast.tpd._, ast.untpd
+import dotty.tools.dotc.ast.{tpd, Trees, untpd}, ast.tpd._
import printing.Texts._
import printing.Printer
import io.AbstractFile
@@ -815,19 +816,26 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
*/
protected def readAnnotationContents(end: Int)(implicit ctx: Context): Tree = {
val atp = readTypeRef()
- val args = new ListBuffer[Tree]
- while (readIndex != end) {
- val argref = readNat()
- args += {
- if (isNameEntry(argref)) {
- val name = at(argref, readName)
- val arg = readClassfileAnnotArg(readNat())
- NamedArg(name.asTermName, arg)
- } else readAnnotArg(argref)
+ val args = {
+ val t = new ListBuffer[Tree]
+
+ while (readIndex != end) {
+ val argref = readNat()
+ t += {
+ if (isNameEntry(argref)) {
+ val name = at(argref, readName)
+ val arg = readClassfileAnnotArg(readNat())
+ NamedArg(name.asTermName, arg)
+ } else readAnnotArg(argref)
+ }
}
+ t.toList
}
- New(atp, args.toList)
- }
+ // println(atp)
+ val targs = atp.argTypes
+
+ 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