aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/ast/TreeInfo.scala15
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala6
-rw-r--r--src/dotty/tools/dotc/core/Flags.scala18
-rw-r--r--src/dotty/tools/dotc/core/pickling/ClassfileConstants.scala2
-rw-r--r--src/dotty/tools/dotc/core/pickling/ClassfileParser.scala5
-rw-r--r--src/dotty/tools/dotc/core/pickling/PickleBuffer.scala2
-rw-r--r--src/dotty/tools/dotc/printing/PlainPrinter.scala2
-rw-r--r--src/dotty/tools/dotc/transform/ExplicitOuter.scala10
-rw-r--r--src/dotty/tools/dotc/transform/Mixin.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala7
10 files changed, 43 insertions, 26 deletions
diff --git a/src/dotty/tools/dotc/ast/TreeInfo.scala b/src/dotty/tools/dotc/ast/TreeInfo.scala
index 51e1ff16f..8163c8bcc 100644
--- a/src/dotty/tools/dotc/ast/TreeInfo.scala
+++ b/src/dotty/tools/dotc/ast/TreeInfo.scala
@@ -26,15 +26,18 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
/** Is tree legal as a member definition of an interface?
*/
- def isInterfaceMember(tree: Tree): Boolean = unsplice(tree) match {
- case EmptyTree => true
- case Import(_, _) => true
- case TypeDef(_, _, _) => true
- case DefDef(mods, _, _, _, _, __) => mods.flags is Deferred
- case ValDef(mods, _, _, _) => mods is Deferred
+ def isPureInterfaceMember(tree: Tree): Boolean = unsplice(tree) match {
+ case EmptyTree | Import(_, _) | TypeDef(_, _, _) => true
+ case DefDef(_, _, _, _, _, rhs) => rhs.isEmpty
+ case ValDef(mods, _, _, rhs) => rhs.isEmpty
case _ => false
}
+ /** Is tree legal as a member definition of a no-init trait?
+ */
+ def isNoInitMember(tree: Tree): Boolean =
+ isPureInterfaceMember(tree) || unsplice(tree).isInstanceOf[DefDef]
+
def isOpAssign(tree: Tree) = unsplice(tree) match {
case Apply(fn, _ :: Nil) =>
unsplice(fn) match {
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala
index b1c2baff6..d78e09418 100644
--- a/src/dotty/tools/dotc/core/Definitions.scala
+++ b/src/dotty/tools/dotc/core/Definitions.scala
@@ -191,7 +191,7 @@ class Definitions {
lazy val ScalaStaticsClass = ScalaStaticsModule.moduleClass.asClass
def staticsMethod(name: PreName) = ctx.requiredMethod(ScalaStaticsClass, name)
-
+
lazy val DottyPredefModule = ctx.requiredModule("dotty.DottyPredef")
lazy val NilModule = ctx.requiredModule("scala.collection.immutable.Nil")
lazy val PredefConformsClass = ctx.requiredClass("scala.Predef." + tpnme.Conforms)
@@ -201,7 +201,7 @@ class Definitions {
// needed as a synthetic class because Scala 2.x refers to it in classfiles
// but does not define it as an explicit class.
newCompleteClassSymbol(
- ScalaPackageClass, tpnme.Singleton, Trait | Interface | Final,
+ ScalaPackageClass, tpnme.Singleton, PureInterfaceCreationFlags | Final,
List(AnyClass.typeRef), EmptyScope)
lazy val SeqClass: ClassSymbol = ctx.requiredClass("scala.collection.Seq")
lazy val Seq_apply = ctx.requiredMethod(SeqClass, nme.apply)
@@ -506,7 +506,7 @@ class Definitions {
val cls = newClassSymbol(
ScalaPackageClass,
traitName,
- Trait | Interface | Synthetic,
+ PureInterfaceCreationFlags | Synthetic,
completer)
myLambdaTraits += cls
cls
diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala
index 804f6af1a..db969767b 100644
--- a/src/dotty/tools/dotc/core/Flags.scala
+++ b/src/dotty/tools/dotc/core/Flags.scala
@@ -287,7 +287,7 @@ object Flags {
/** A trait that has only abstract methods as members
* (and therefore can be represented by a Java interface
*/
- final val Interface = typeFlag(22, "interface")
+ final val PureInterface = typeFlag(22, "interface")
/** Labeled with of abstract & override */
final val AbsOverride = termFlag(22, "abstract override")
@@ -335,6 +335,9 @@ object Flags {
final val JavaStaticTerm = JavaStatic.toTermFlags
final val JavaStaticType = JavaStatic.toTypeFlags
+ /** Trait is not an interface, but does not have fields or intialization code */
+ final val NoInits = typeFlag(32, "<noInits>")
+
/** Variable is accessed from nested function. */
final val Captured = termFlag(32, "<captured>")
@@ -353,9 +356,6 @@ 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>")
-
// Flags following this one are not pickled
/** Symbol always defines a fresh named type */
@@ -464,6 +464,9 @@ object Flags {
/** Accessors always have these flags set */
final val AccessorCreationFlags = Method | Accessor
+ /** Pure interfaces always have these flags */
+ final val PureInterfaceCreationFlags = Trait | NoInits | PureInterface
+
/** The flags of the self symbol */
final val SelfSymFlags = Private | Local | Deferred
@@ -539,8 +542,11 @@ object Flags {
/** Is a default parameter in Scala 2*/
final val DefaultParameter = allOf(Param, DefaultParameterized)
- /** A Java interface */
- final val JavaInterface = allOf(JavaDefined, Trait)
+ /** A trait that does not need to be initialized */
+ final val NoInitsTrait = allOf(Trait, NoInits)
+
+ /** A Java interface, potentially with default methods */
+ final val JavaTrait = allOf(JavaDefined, Trait, NoInits)
/** A Java companion object */
final val JavaModule = allOf(JavaDefined, Module)
diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileConstants.scala b/src/dotty/tools/dotc/core/pickling/ClassfileConstants.scala
index c35b9ca47..158f6b409 100644
--- a/src/dotty/tools/dotc/core/pickling/ClassfileConstants.scala
+++ b/src/dotty/tools/dotc/core/pickling/ClassfileConstants.scala
@@ -345,7 +345,7 @@ object ClassfileConstants {
case JAVA_ACC_SYNTHETIC => Synthetic
case JAVA_ACC_STATIC => JavaStatic
case JAVA_ACC_ABSTRACT => if (isAnnotation) EmptyFlags else if (isClass) Abstract else Deferred
- case JAVA_ACC_INTERFACE => if (isAnnotation) EmptyFlags else JavaInterface
+ case JAVA_ACC_INTERFACE => if (isAnnotation) EmptyFlags else PureInterfaceCreationFlags | JavaDefined
case _ => EmptyFlags
}
diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
index 67f825502..f2a5e4171 100644
--- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
+++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
@@ -503,8 +503,9 @@ class ClassfileParser(
parseExceptions(attrLen)
case tpnme.CodeATTR =>
- if (sym.owner is Flags.Interface) {
- sym.setFlag(Flags.DefaultMethod)
+ if (sym.owner is Flags.JavaTrait) {
+ sym.resetFlag(Flags.Deferred)
+ sym.owner.resetFlag(Flags.PureInterface)
ctx.log(s"$sym in ${sym.owner} is a java8+ default method.")
}
in.skip(attrLen)
diff --git a/src/dotty/tools/dotc/core/pickling/PickleBuffer.scala b/src/dotty/tools/dotc/core/pickling/PickleBuffer.scala
index d2a05bf3a..9f8d4fc2d 100644
--- a/src/dotty/tools/dotc/core/pickling/PickleBuffer.scala
+++ b/src/dotty/tools/dotc/core/pickling/PickleBuffer.scala
@@ -220,7 +220,7 @@ object PickleBuffer {
DEFERRED_PKL -> Deferred,
FINAL_PKL -> Final,
METHOD_PKL -> Method,
- INTERFACE_PKL -> Interface,
+ INTERFACE_PKL -> PureInterface,
MODULE_PKL -> Module,
IMPLICIT_PKL -> Implicit,
SEALED_PKL -> Sealed,
diff --git a/src/dotty/tools/dotc/printing/PlainPrinter.scala b/src/dotty/tools/dotc/printing/PlainPrinter.scala
index 78ee32b98..ffbae59bb 100644
--- a/src/dotty/tools/dotc/printing/PlainPrinter.scala
+++ b/src/dotty/tools/dotc/printing/PlainPrinter.scala
@@ -296,7 +296,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
/** String representation of symbol's definition key word */
protected def keyString(sym: Symbol): String = {
val flags = sym.flagsUNSAFE
- if (flags is JavaInterface) "interface"
+ if (flags is JavaTrait) "interface"
else if ((flags is Trait) && !(flags is ImplClass)) "trait"
else if (sym.isClass) "class"
else if (sym.isType) "type"
diff --git a/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/src/dotty/tools/dotc/transform/ExplicitOuter.scala
index 28d742b5e..436d9bcf7 100644
--- a/src/dotty/tools/dotc/transform/ExplicitOuter.scala
+++ b/src/dotty/tools/dotc/transform/ExplicitOuter.scala
@@ -144,11 +144,11 @@ object ExplicitOuter {
nme.OUTER.expandedName(cls)
/** Class needs an outer pointer, provided there is a reference to an outer this in it. */
- def needsOuterIfReferenced(cls: ClassSymbol)(implicit ctx: Context): Boolean = !(
- cls.isStatic ||
- cls.owner.enclosingClass.isStaticOwner ||
- cls.is(Interface)
- )
+ def needsOuterIfReferenced(cls: ClassSymbol)(implicit ctx: Context): Boolean =
+ !(cls.isStatic ||
+ cls.owner.enclosingClass.isStaticOwner ||
+ cls.is(PureInterface)
+ )
/** Class unconditionally needs an outer pointer. This is the case if
* the class needs an outer pointer if referenced and one of the following holds:
diff --git a/src/dotty/tools/dotc/transform/Mixin.scala b/src/dotty/tools/dotc/transform/Mixin.scala
index 1d342404a..3d68a2687 100644
--- a/src/dotty/tools/dotc/transform/Mixin.scala
+++ b/src/dotty/tools/dotc/transform/Mixin.scala
@@ -134,7 +134,7 @@ class Mixin extends MiniPhaseTransform with SymTransformer { thisTransform =>
case Some(call) =>
if (defn.PhantomClasses.contains(baseCls)) Nil else call :: Nil
case None =>
- if (baseCls.is(Interface) || defn.PhantomClasses.contains(baseCls)) Nil
+ if (baseCls.is(NoInitsTrait) || defn.PhantomClasses.contains(baseCls)) Nil
else {
//println(i"synth super call ${baseCls.primaryConstructor}: ${baseCls.primaryConstructor.info}")
superRef(baseCls.primaryConstructor).appliedToNone :: Nil
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index 3a1f0a98b..e8bb1b9e7 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -492,6 +492,13 @@ class Namer { typer: Typer =>
index(rest)(inClassContext(selfInfo))
denot.info = ClassInfo(cls.owner.thisType, cls, parentRefs, decls, selfInfo)
+ if (cls is Trait) {
+ if (body forall isNoInitMember) {
+ cls.setFlag(NoInits)
+ if (body forall isPureInterfaceMember)
+ cls.setFlag(PureInterface)
+ }
+ }
}
}