Skip to content

Various small improvements to prepare for transparent methods #4620

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Jun 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
case t: TypeApply if (t.fun.symbol == Predef_classOf) =>
av.visit(name, t.args.head.tpe.classSymbol.denot.info.toTypeKind(bcodeStore)(innerClasesStore).toASMType)
case t: tpd.Select =>
if (t.symbol.denot.owner.is(Flags.Enum)) {
if (t.symbol.denot.owner.is(Flags.JavaEnum)) {
val edesc = innerClasesStore.typeDescriptor(t.tpe.asInstanceOf[bcodeStore.int.Type]) // the class descriptor of the enumeration class.
val evalue = t.symbol.name.mangledString // value the actual enumeration value.
av.visitEnum(name, edesc, evalue)
Expand Down Expand Up @@ -710,7 +710,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
def isBottomClass: Boolean = (sym ne defn.NullClass) && (sym ne defn.NothingClass)
def isBridge: Boolean = sym is Flags.Bridge
def isArtifact: Boolean = sym is Flags.Artifact
def hasEnumFlag: Boolean = sym is Flags.Enum
def hasEnumFlag: Boolean = sym is Flags.JavaEnum
def hasAccessBoundary: Boolean = sym.accessBoundary(defn.RootClass) ne defn.RootClass
def isVarargsMethod: Boolean = sym is Flags.JavaVarargs
def isDeprecated: Boolean = false
Expand Down
17 changes: 6 additions & 11 deletions compiler/src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,8 @@ object desugar {
val isCaseClass = mods.is(Case) && !mods.is(Module)
val isCaseObject = mods.is(Case) && mods.is(Module)
val isImplicit = mods.is(Implicit)
val isEnum = mods.hasMod[Mod.Enum] && !mods.is(Module)
val isEnumCase = mods.hasMod[Mod.EnumCase]
val isEnum = mods.isEnumClass && !mods.is(Module)
def isEnumCase = mods.isEnumCase
val isValueClass = parents.nonEmpty && isAnyVal(parents.head)
// This is not watertight, but `extends AnyVal` will be replaced by `inline` later.

Expand Down Expand Up @@ -641,7 +641,7 @@ object desugar {
val moduleName = checkNotReservedName(mdef).asTermName
val impl = mdef.impl
val mods = mdef.mods
lazy val isEnumCase = mods.hasMod[Mod.EnumCase]
def isEnumCase = mods.isEnumCase
if (mods is Package)
PackageDef(Ident(moduleName), cpy.ModuleDef(mdef)(nme.PACKAGE, impl).withMods(mods &~ Package) :: Nil)
else if (isEnumCase)
Expand Down Expand Up @@ -688,7 +688,7 @@ object desugar {
*/
def patDef(pdef: PatDef)(implicit ctx: Context): Tree = flatTree {
val PatDef(mods, pats, tpt, rhs) = pdef
if (mods.hasMod[Mod.EnumCase])
if (mods.isEnumCase)
pats map {
case id: Ident =>
expandSimpleEnumCase(id.name.asTermName, mods,
Expand Down Expand Up @@ -810,16 +810,11 @@ object desugar {
* ==>
* def $anonfun(params) = body
* Closure($anonfun)
*
* If `inlineable` is true, tag $anonfun with an @inline annotation.
*/
def makeClosure(params: List[ValDef], body: Tree, tpt: Tree = TypeTree(), isInlineable: Boolean, isImplicit: Boolean)(implicit ctx: Context) = {
var mods = synthetic | Artifact
if (isInlineable) mods |= Inline
def makeClosure(params: List[ValDef], body: Tree, tpt: Tree = TypeTree(), isImplicit: Boolean)(implicit ctx: Context) =
Block(
DefDef(nme.ANON_FUN, Nil, params :: Nil, tpt, body).withMods(mods),
DefDef(nme.ANON_FUN, Nil, params :: Nil, tpt, body).withMods(synthetic | Artifact),
Closure(Nil, Ident(nme.ANON_FUN), if (isImplicit) ImplicitEmptyTree else EmptyTree))
}

/** If `nparams` == 1, expand partial function
*
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ object DesugarEnums {

/** Is `tree` an (untyped) enum case? */
def isEnumCase(tree: Tree)(implicit ctx: Context): Boolean = tree match {
case tree: MemberDef => tree.mods.hasMod[Mod.EnumCase]
case PatDef(mods, _, _, _) => mods.hasMod[Mod.EnumCase]
case tree: MemberDef => tree.mods.isEnumCase
case PatDef(mods, _, _, _) => mods.isEnumCase
case _ => false
}

Expand Down Expand Up @@ -69,7 +69,7 @@ object DesugarEnums {

/** Add implied flags to an enum class or an enum case */
def addEnumFlags(cdef: TypeDef)(implicit ctx: Context) =
if (cdef.mods.hasMod[Mod.Enum]) cdef.withMods(cdef.mods.withFlags(cdef.mods.flags | Abstract | Sealed))
if (cdef.mods.isEnumClass) cdef.withMods(cdef.mods.withFlags(cdef.mods.flags | Abstract | Sealed))
else if (isEnumCase(cdef)) cdef.withMods(cdef.mods.withFlags(cdef.mods.flags | Final))
else cdef

Expand Down
38 changes: 24 additions & 14 deletions compiler/src/dotty/tools/dotc/ast/untpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {

case class Inline() extends Mod(Flags.Inline)

case class Enum() extends Mod(Flags.EmptyFlags)

case class EnumCase() extends Mod(Flags.EmptyFlags)
case class Enum() extends Mod(Flags.Enum)
}

/** Modifiers and annotations for definitions
Expand Down Expand Up @@ -165,15 +163,26 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
if (this.flags == flags) this
else copy(flags = flags)

def withAddedMod(mod: Mod): Modifiers =
if (mods.exists(_ eq mod)) this
else withMods(mods :+ mod)
def withAddedMod(mod: Mod): Modifiers =
if (mods.exists(_ eq mod)) this
else withMods(mods :+ mod)

def withMods(ms: List[Mod]): Modifiers =
if (mods eq ms) this
else copy(mods = ms)
/** Modifiers with given list of Mods. It is checked that
* all modifiers are already accounted for in `flags` and `privateWithin`.
*/
def withMods(ms: List[Mod]): Modifiers = {
if (mods eq ms) this
else {
if (ms.nonEmpty)
for (m <- ms)
assert(flags.is(m.flags) ||
m.isInstanceOf[Mod.Private] && !privateWithin.isEmpty,
s"unaccounted modifier: $m in $this when adding $ms")
copy(mods = ms)
}
}

def withAddedAnnotation(annot: Tree): Modifiers =
def withAddedAnnotation(annot: Tree): Modifiers =
if (annotations.exists(_ eq annot)) this
else withAnnotations(annotations :+ annot)

Expand All @@ -188,10 +197,11 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
def hasFlags = flags != EmptyFlags
def hasAnnotations = annotations.nonEmpty
def hasPrivateWithin = privateWithin != tpnme.EMPTY
def hasMod[T: ClassTag] = {
val cls = implicitly[ClassTag[T]].runtimeClass
mods.exists(mod => cls.isAssignableFrom(mod.getClass))
}

private def isEnum = is(Enum, butNot = JavaDefined)

def isEnumCase = isEnum && is(Case)
def isEnumClass = isEnum && !is(Case)
}

@sharable val EmptyModifiers: Modifiers = new Modifiers()
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ class ScalaSettings extends Settings.SettingGroup {
val YdebugFlags = BooleanSetting("-Ydebug-flags", "Print all flags of definitions")
val YdebugMissingRefs = BooleanSetting("-Ydebug-missing-refs", "Print a stacktrace when a required symbol is missing")
val YdebugNames = BooleanSetting("-Ydebug-names", "Show internal representation of names")
val YdebugOwners = BooleanSetting("-Ydebug-owners", "Print all owners of definitions (requires -Yprint-syms)")
val YtermConflict = ChoiceSetting("-Yresolve-term-conflict", "strategy", "Resolve term conflicts", List("package", "object", "error"), "error")
val Ylog = PhasesSetting("-Ylog", "Log operations during")
val YemitTasty = BooleanSetting("-Yemit-tasty", "Generate tasty in separate *.tasty file.")
Expand All @@ -113,6 +112,7 @@ class ScalaSettings extends Settings.SettingGroup {
val YplainPrinter = BooleanSetting("-Yplain-printer", "Pretty-print using a plain printer.")
val YprintSyms = BooleanSetting("-Yprint-syms", "when printing trees print info in symbols instead of corresponding info in trees.")
val YprintDebug = BooleanSetting("-Yprint-debug", "when printing trees, print some extra information useful for debugging.")
val YprintDebugOwners = BooleanSetting("-Yprint-debug-owners", "when printing trees, print owners of definitions.")
val YshowPrintErrors = BooleanSetting("-Yshow-print-errors", "don't suppress exceptions thrown during tree printing.")
val YtestPickler = BooleanSetting("-Ytest-pickler", "self-test for pickling functionality; should be used with -Ystop-after:pickler")
val YcheckReentrant = BooleanSetting("-Ycheck-reentrant", "check that compiled program does not contain vars that can be accessed from a global root.")
Expand Down
12 changes: 12 additions & 0 deletions compiler/src/dotty/tools/dotc/core/Flags.scala
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,9 @@ object Flags {
/** An inline parameter */
final val InlineParam = allOf(Inline, Param)

/** An enum case */
final val EnumCase = allOf(Enum, Case)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation for Enum needs to be updated:

   /** Symbol is a Java enum */
   final val Enum = commonFlag(40, "<enum>")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's done in the latest commit.


/** A term parameter or parameter accessor */
final val TermParamOrAccessor = Param | ParamAccessor

Expand Down Expand Up @@ -620,6 +623,15 @@ object Flags {
/** A Java companion object */
final val JavaProtected = allOf(JavaDefined, Protected)

/** A Java enum */
final val JavaEnum = allOf(JavaDefined, Enum)

/** A Java enum trait */
final val JavaEnumTrait = allOf(JavaDefined, Enum)

/** A Java enum value */
final val JavaEnumValue = allOf(Stable, JavaStatic, JavaDefined, Enum)

/** Labeled private[this] */
final val PrivateLocal = allOf(Private, Local)

Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1826,7 +1826,7 @@ object Types {

private def setDenot(denot: Denotation)(implicit ctx: Context): Unit = {
if (ctx.isAfterTyper)
assert(!denot.isOverloaded, this)
assert(!denot.isOverloaded || ctx.mode.is(Mode.Printing), this)
if (Config.checkNoDoubleBindings)
if (ctx.settings.YnoDoubleBindings.value)
checkSymAssign(denot.symbol)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ class ClassfileParser(
if (isEnum) {
instanceScope.toList.map(_.ensureCompleted())
staticScope.toList.map(_.ensureCompleted())
classRoot.setFlag(Flags.Enum)
moduleRoot.setFlag(Flags.Enum)
classRoot.setFlag(Flags.JavaEnum)
moduleRoot.setFlag(Flags.JavaEnum)
}

result
Expand Down
40 changes: 21 additions & 19 deletions compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ Standard-Section: "ASTs" TopLevelStat*

// Imports are for scala.meta, they are not used in the backend

TypeParam = TYPEPARAM Length NameRef Type Modifier*
TypeParam = TYPEPARAM Length NameRef type_Term Modifier*
Params = PARAMS Length Param*
Param = PARAM Length NameRef Type rhs_Term? Modifier* // rhs_Term is present in the case of an aliased class parameter
Param = PARAM Length NameRef type_Term rhs_Term? Modifier* // rhs_Term is present in the case of an aliased class parameter
Template = TEMPLATE Length TypeParam* Param* parent_Term* Self? Stat* // Stat* always starts with the primary constructor.
Self = SELFDEF selfName_NameRef selfType_Type
Self = SELFDEF selfName_NameRef selfType_Term

Term = Path
IDENT NameRef Type // used when term ident’s type is not a TermRef
Expand Down Expand Up @@ -184,6 +184,7 @@ Standard-Section: "ASTs" TopLevelStat*
STATIC // mapped to static Java member
OBJECT // an object or its class
TRAIT // a trait
ENUM // a enum class or enum case
LOCAL // private[this] or protected[this]
SYNTHETIC // generated by Scala compiler
ARTIFACT // to be tagged Java Synthetic
Expand Down Expand Up @@ -225,7 +226,7 @@ Standard Section: "Positions" Assoc*
object TastyFormat {

final val header = Array(0x5C, 0xA1, 0xAB, 0x1F)
val MajorVersion = 8
val MajorVersion = 9
val MinorVersion = 0

/** Tags used to serialize names */
Expand Down Expand Up @@ -282,21 +283,22 @@ object TastyFormat {
final val STATIC = 17
final val OBJECT = 18
final val TRAIT = 19
final val LOCAL = 20
final val SYNTHETIC = 21
final val ARTIFACT = 22
final val MUTABLE = 23
final val LABEL = 24
final val FIELDaccessor = 25
final val CASEaccessor = 26
final val COVARIANT = 27
final val CONTRAVARIANT = 28
final val SCALA2X = 29
final val DEFAULTparameterized = 30
final val STABLE = 31
final val MACRO = 32
final val ERASED = 33
final val PARAMsetter = 34
final val ENUM = 20
final val LOCAL = 21
final val SYNTHETIC = 22
final val ARTIFACT = 23
final val MUTABLE = 24
final val LABEL = 25
final val FIELDaccessor = 26
final val CASEaccessor = 27
final val COVARIANT = 28
final val CONTRAVARIANT = 29
final val SCALA2X = 30
final val DEFAULTparameterized = 31
final val STABLE = 32
final val MACRO = 33
final val ERASED = 34
final val PARAMsetter = 35

// Cat. 2: tag Nat

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class TastyPrinter(bytes: Array[Byte])(implicit ctx: Context) {
printName(); printName()
case VALDEF | DEFDEF | TYPEDEF | TYPEPARAM | PARAM | NAMEDARG | BIND =>
printName(); printTrees()
case REFINEDtype =>
case REFINEDtype | TERMREFin | TYPEREFin =>
printName(); printTree(); printTrees()
case RETURN | HOLE =>
printNat(); printTrees()
Expand Down
25 changes: 13 additions & 12 deletions compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -504,16 +504,7 @@ class TreePickler(pickler: TastyPickler) {
}
case Import(expr, selectors) =>
writeByte(IMPORT)
withLength {
pickleTree(expr)
selectors foreach {
case Thicket((from @ Ident(_)) :: (to @ Ident(_)) :: Nil) =>
pickleSelector(IMPORTED, from)
pickleSelector(RENAMED, to)
case id @ Ident(_) =>
pickleSelector(IMPORTED, id)
}
}
withLength { pickleTree(expr); pickleSelectors(selectors) }
case PackageDef(pid, stats) =>
writeByte(PACKAGE)
withLength { pickleType(pid.tpe); pickleStats(stats) }
Expand Down Expand Up @@ -569,6 +560,15 @@ class TreePickler(pickler: TastyPickler) {
}
}

def pickleSelectors(selectors: List[untpd.Tree])(implicit ctx: Context): Unit =
selectors foreach {
case Thicket((from @ Ident(_)) :: (to @ Ident(_)) :: Nil) =>
pickleSelector(IMPORTED, from)
pickleSelector(RENAMED, to)
case id @ Ident(_) =>
pickleSelector(IMPORTED, id)
}

def pickleSelector(tag: Int, id: untpd.Ident)(implicit ctx: Context): Unit = {
registerTreeAddr(id)
writeByte(tag)
Expand All @@ -592,22 +592,23 @@ class TreePickler(pickler: TastyPickler) {
if (flags is Macro) writeByte(MACRO)
if (flags is JavaStatic) writeByte(STATIC)
if (flags is Module) writeByte(OBJECT)
if (flags is Enum) writeByte(ENUM)
if (flags is Local) writeByte(LOCAL)
if (flags is Synthetic) writeByte(SYNTHETIC)
if (flags is Artifact) writeByte(ARTIFACT)
if (flags is Scala2x) writeByte(SCALA2X)
if (sym.isTerm) {
if (flags is Implicit) writeByte(IMPLICIT)
if (flags is Erased) writeByte(ERASED)
if ((flags is Lazy) && !(sym is Module)) writeByte(LAZY)
if (flags.is(Lazy, butNot = Module)) writeByte(LAZY)
if (flags is AbsOverride) { writeByte(ABSTRACT); writeByte(OVERRIDE) }
if (flags is Mutable) writeByte(MUTABLE)
if (flags is Accessor) writeByte(FIELDaccessor)
if (flags is CaseAccessor) writeByte(CASEaccessor)
if (flags is DefaultParameterized) writeByte(DEFAULTparameterized)
if (flags is Stable) writeByte(STABLE)
if ((flags is ParamAccessor) && sym.isSetter) writeByte(PARAMsetter)
if ((flags is Label)) writeByte(LABEL)
if (flags is Label) writeByte(LABEL)
} else {
if (flags is Sealed) writeByte(SEALED)
if (flags is Abstract) writeByte(ABSTRACT)
Expand Down
Loading