Skip to content

Commit 892f7bd

Browse files
committed
Merge pull request #219 from dotty-staging/cleanup/interface-rebased
Cleaning up interfaces.
2 parents 42e51d5 + 540479a commit 892f7bd

File tree

11 files changed

+43
-91
lines changed

11 files changed

+43
-91
lines changed

src/dotty/tools/dotc/ast/TreeInfo.scala

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,18 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
2626

2727
/** Is tree legal as a member definition of an interface?
2828
*/
29-
def isInterfaceMember(tree: Tree): Boolean = unsplice(tree) match {
30-
case EmptyTree => true
31-
case Import(_, _) => true
32-
case TypeDef(_, _, _) => true
33-
case DefDef(mods, _, _, _, _, __) => mods.flags is Deferred
34-
case ValDef(mods, _, _, _) => mods is Deferred
29+
def isPureInterfaceMember(tree: Tree): Boolean = unsplice(tree) match {
30+
case EmptyTree | Import(_, _) | TypeDef(_, _, _) => true
31+
case DefDef(_, _, _, _, _, rhs) => rhs.isEmpty
32+
case ValDef(mods, _, _, rhs) => rhs.isEmpty
3533
case _ => false
3634
}
3735

36+
/** Is tree legal as a member definition of a no-init trait?
37+
*/
38+
def isNoInitMember(tree: Tree): Boolean =
39+
isPureInterfaceMember(tree) || unsplice(tree).isInstanceOf[DefDef]
40+
3841
def isOpAssign(tree: Tree) = unsplice(tree) match {
3942
case Apply(fn, _ :: Nil) =>
4043
unsplice(fn) match {

src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ class Definitions {
191191
lazy val ScalaStaticsClass = ScalaStaticsModule.moduleClass.asClass
192192

193193
def staticsMethod(name: PreName) = ctx.requiredMethod(ScalaStaticsClass, name)
194-
194+
195195
lazy val DottyPredefModule = ctx.requiredModule("dotty.DottyPredef")
196196
lazy val NilModule = ctx.requiredModule("scala.collection.immutable.Nil")
197197
lazy val PredefConformsClass = ctx.requiredClass("scala.Predef." + tpnme.Conforms)
@@ -201,7 +201,7 @@ class Definitions {
201201
// needed as a synthetic class because Scala 2.x refers to it in classfiles
202202
// but does not define it as an explicit class.
203203
newCompleteClassSymbol(
204-
ScalaPackageClass, tpnme.Singleton, Trait | Interface | Final,
204+
ScalaPackageClass, tpnme.Singleton, PureInterfaceCreationFlags | Final,
205205
List(AnyClass.typeRef), EmptyScope)
206206
lazy val SeqClass: ClassSymbol = ctx.requiredClass("scala.collection.Seq")
207207
lazy val Seq_apply = ctx.requiredMethod(SeqClass, nme.apply)
@@ -506,7 +506,7 @@ class Definitions {
506506
val cls = newClassSymbol(
507507
ScalaPackageClass,
508508
traitName,
509-
Trait | Interface | Synthetic,
509+
PureInterfaceCreationFlags | Synthetic,
510510
completer)
511511
myLambdaTraits += cls
512512
cls

src/dotty/tools/dotc/core/Flags.scala

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ object Flags {
287287
/** A trait that has only abstract methods as members
288288
* (and therefore can be represented by a Java interface
289289
*/
290-
final val Interface = typeFlag(22, "interface")
290+
final val PureInterface = typeFlag(22, "interface")
291291

292292
/** Labeled with of abstract & override */
293293
final val AbsOverride = termFlag(22, "abstract override")
@@ -335,6 +335,9 @@ object Flags {
335335
final val JavaStaticTerm = JavaStatic.toTermFlags
336336
final val JavaStaticType = JavaStatic.toTypeFlags
337337

338+
/** Trait is not an interface, but does not have fields or intialization code */
339+
final val NoInits = typeFlag(32, "<noInits>")
340+
338341
/** Variable is accessed from nested function. */
339342
final val Captured = termFlag(32, "<captured>")
340343

@@ -353,9 +356,6 @@ object Flags {
353356
/** Symbol is a Java-style varargs method */
354357
final val JavaVarargs = termFlag(37, "<varargs>")
355358

356-
/** Symbol is a Java default method */
357-
final val DefaultMethod = termFlag(38, "<defaultmethod>")
358-
359359
// Flags following this one are not pickled
360360

361361
/** Symbol always defines a fresh named type */
@@ -464,6 +464,9 @@ object Flags {
464464
/** Accessors always have these flags set */
465465
final val AccessorCreationFlags = Method | Accessor
466466

467+
/** Pure interfaces always have these flags */
468+
final val PureInterfaceCreationFlags = Trait | NoInits | PureInterface
469+
467470
/** The flags of the self symbol */
468471
final val SelfSymFlags = Private | Local | Deferred
469472

@@ -539,8 +542,11 @@ object Flags {
539542
/** Is a default parameter in Scala 2*/
540543
final val DefaultParameter = allOf(Param, DefaultParameterized)
541544

542-
/** A Java interface */
543-
final val JavaInterface = allOf(JavaDefined, Trait)
545+
/** A trait that does not need to be initialized */
546+
final val NoInitsTrait = allOf(Trait, NoInits)
547+
548+
/** A Java interface, potentially with default methods */
549+
final val JavaTrait = allOf(JavaDefined, Trait, NoInits)
544550

545551
/** A Java companion object */
546552
final val JavaModule = allOf(JavaDefined, Module)

src/dotty/tools/dotc/core/pickling/ClassfileConstants.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ object ClassfileConstants {
345345
case JAVA_ACC_SYNTHETIC => Synthetic
346346
case JAVA_ACC_STATIC => JavaStatic
347347
case JAVA_ACC_ABSTRACT => if (isAnnotation) EmptyFlags else if (isClass) Abstract else Deferred
348-
case JAVA_ACC_INTERFACE => if (isAnnotation) EmptyFlags else JavaInterface
348+
case JAVA_ACC_INTERFACE => if (isAnnotation) EmptyFlags else PureInterfaceCreationFlags | JavaDefined
349349
case _ => EmptyFlags
350350
}
351351

src/dotty/tools/dotc/core/pickling/ClassfileParser.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -503,8 +503,9 @@ class ClassfileParser(
503503
parseExceptions(attrLen)
504504

505505
case tpnme.CodeATTR =>
506-
if (sym.owner is Flags.Interface) {
507-
sym.setFlag(Flags.DefaultMethod)
506+
if (sym.owner is Flags.JavaTrait) {
507+
sym.resetFlag(Flags.Deferred)
508+
sym.owner.resetFlag(Flags.PureInterface)
508509
ctx.log(s"$sym in ${sym.owner} is a java8+ default method.")
509510
}
510511
in.skip(attrLen)

src/dotty/tools/dotc/core/pickling/PickleBuffer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ object PickleBuffer {
220220
DEFERRED_PKL -> Deferred,
221221
FINAL_PKL -> Final,
222222
METHOD_PKL -> Method,
223-
INTERFACE_PKL -> Interface,
223+
INTERFACE_PKL -> PureInterface,
224224
MODULE_PKL -> Module,
225225
IMPLICIT_PKL -> Implicit,
226226
SEALED_PKL -> Sealed,

src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
296296
/** String representation of symbol's definition key word */
297297
protected def keyString(sym: Symbol): String = {
298298
val flags = sym.flagsUNSAFE
299-
if (flags is JavaInterface) "interface"
299+
if (flags is JavaTrait) "interface"
300300
else if ((flags is Trait) && !(flags is ImplClass)) "trait"
301301
else if (sym.isClass) "class"
302302
else if (sym.isType) "type"

src/dotty/tools/dotc/transform/AttachOuter.scala

Lines changed: 0 additions & 65 deletions
This file was deleted.

src/dotty/tools/dotc/transform/ExplicitOuter.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,11 @@ object ExplicitOuter {
144144
nme.OUTER.expandedName(cls)
145145

146146
/** Class needs an outer pointer, provided there is a reference to an outer this in it. */
147-
def needsOuterIfReferenced(cls: ClassSymbol)(implicit ctx: Context): Boolean = !(
148-
cls.isStatic ||
149-
cls.owner.enclosingClass.isStaticOwner ||
150-
cls.is(Interface)
151-
)
147+
def needsOuterIfReferenced(cls: ClassSymbol)(implicit ctx: Context): Boolean =
148+
!(cls.isStatic ||
149+
cls.owner.enclosingClass.isStaticOwner ||
150+
cls.is(PureInterface)
151+
)
152152

153153
/** Class unconditionally needs an outer pointer. This is the case if
154154
* the class needs an outer pointer if referenced and one of the following holds:

src/dotty/tools/dotc/transform/Mixin.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ class Mixin extends MiniPhaseTransform with SymTransformer { thisTransform =>
134134
case Some(call) =>
135135
if (defn.PhantomClasses.contains(baseCls)) Nil else call :: Nil
136136
case None =>
137-
if (baseCls.is(Interface) || defn.PhantomClasses.contains(baseCls)) Nil
137+
if (baseCls.is(NoInitsTrait) || defn.PhantomClasses.contains(baseCls)) Nil
138138
else {
139139
//println(i"synth super call ${baseCls.primaryConstructor}: ${baseCls.primaryConstructor.info}")
140140
superRef(baseCls.primaryConstructor).appliedToNone :: Nil

src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,13 @@ class Namer { typer: Typer =>
492492

493493
index(rest)(inClassContext(selfInfo))
494494
denot.info = ClassInfo(cls.owner.thisType, cls, parentRefs, decls, selfInfo)
495+
if (cls is Trait) {
496+
if (body forall isNoInitMember) {
497+
cls.setFlag(NoInits)
498+
if (body forall isPureInterfaceMember)
499+
cls.setFlag(PureInterface)
500+
}
501+
}
495502
}
496503
}
497504

0 commit comments

Comments
 (0)