Skip to content

Drop modifiers #1539

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 4 commits into from
Sep 30, 2016
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
8 changes: 4 additions & 4 deletions src/dotty/tools/backend/jvm/DottyBackendInterface.scala
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
type Bind = tpd.Bind
type New = tpd.New
type Super = tpd.Super
type Modifiers = tpd.Modifiers
type Modifiers = Null
type Annotation = Annotations.Annotation
type ArrayValue = tpd.JavaSeqLiteral
type ApplyDynamic = Null
Expand Down Expand Up @@ -944,7 +944,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
}

object ValDef extends ValDefDeconstructor {
def _1: Modifiers = field.mods
def _1: Modifiers = null
def _2: Name = field.name
def _3: Tree = field.tpt
def _4: Tree = field.rhs
Expand Down Expand Up @@ -1055,7 +1055,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
}

object DefDef extends DefDefDeconstructor {
def _1: Modifiers = field.mods
def _1: Modifiers = null
def _2: Name = field.name
def _3: List[TypeDef] = field.tparams
def _4: List[List[ValDef]] = field.vparamss
Expand All @@ -1081,7 +1081,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
}

object ClassDef extends ClassDefDeconstructor {
def _1: Modifiers = field.mods
def _1: Modifiers = null
def _2: Name = field.name
def _4: Template = field.rhs.asInstanceOf[Template]
def _3: List[TypeDef] = Nil
Expand Down
27 changes: 14 additions & 13 deletions src/dotty/tools/dotc/ast/TreeInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -249,17 +249,6 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
/** Is this case guarded? */
def isGuardedCase(cdef: CaseDef) = cdef.guard ne EmptyTree

/** True iff definition is a val or def with no right-hand-side, or it
* is an abstract typoe declaration
*/
def lacksDefinition(mdef: MemberDef)(implicit ctx: Context) = mdef match {
case mdef: ValOrDefDef =>
mdef.unforcedRhs == EmptyTree && !mdef.name.isConstructorName && !mdef.mods.is(ParamAccessor)
case mdef: TypeDef =>
mdef.rhs.isEmpty || mdef.rhs.isInstanceOf[TypeBoundsTree]
case _ => false
}

/** The underlying pattern ignoring any bindings */
def unbind(x: Tree): Tree = unsplice(x) match {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This function was unused, superseded by NavigateAST.

case Bind(_, y) => unbind(y)
Expand All @@ -279,9 +268,21 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>

trait UntypedTreeInfo extends TreeInfo[Untyped] { self: Trees.Instance[Untyped] =>
import TreeInfo._
import untpd._

/** True iff definition is a val or def with no right-hand-side, or it
* is an abstract typoe declaration
*/
def lacksDefinition(mdef: MemberDef)(implicit ctx: Context) = mdef match {
case mdef: ValOrDefDef =>
mdef.unforcedRhs == EmptyTree && !mdef.name.isConstructorName && !mdef.mods.is(ParamAccessor)
case mdef: TypeDef =>
mdef.rhs.isEmpty || mdef.rhs.isInstanceOf[TypeBoundsTree]
case _ => false
}

def isFunctionWithUnknownParamType(tree: Tree) = tree match {
case untpd.Function(args, _) =>
case Function(args, _) =>
args.exists {
case ValDef(_, tpt, _) => tpt.isEmpty
case _ => false
Expand All @@ -307,7 +308,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
| DefDef(_, _, _, _, _) =>
Pure
case vdef @ ValDef(_, _, _) =>
if (vdef.mods is Mutable) Impure else exprPurity(vdef.rhs)
if (vdef.symbol.flags is Mutable) Impure else exprPurity(vdef.rhs)
case _ =>
Impure
}
Expand Down
87 changes: 22 additions & 65 deletions src/dotty/tools/dotc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,51 +33,7 @@ object Trees {
/** Attachment key for trees with documentation strings attached */
val DocComment = new Attachment.Key[Comment]

/** Modifiers and annotations for definitions
* @param flags The set flags
* @param privateWithin If a private or protected has is followed by a
* qualifier [q], the name q, "" as a typename otherwise.
* @param annotations The annotations preceding the modifiers
*/
case class Modifiers[-T >: Untyped] (
flags: FlagSet = EmptyFlags,
privateWithin: TypeName = tpnme.EMPTY,
annotations: List[Tree[T]] = Nil) extends Positioned with Cloneable {

def is(fs: FlagSet): Boolean = flags is fs
def is(fc: FlagConjunction): Boolean = flags is fc

def | (fs: FlagSet): Modifiers[T] = withFlags(flags | fs)
def & (fs: FlagSet): Modifiers[T] = withFlags(flags & fs)
def &~(fs: FlagSet): Modifiers[T] = withFlags(flags &~ fs)

def toTypeFlags: Modifiers[T] = withFlags(flags.toTypeFlags)
def toTermFlags: Modifiers[T] = withFlags(flags.toTermFlags)

def withFlags(flags: FlagSet) =
if (this.flags == flags) this
else copy(flags = flags)

def withAddedAnnotation[U >: Untyped <: T](annot: Tree[U]): Modifiers[U] =
if (annotations.exists(_ eq annot)) this
else withAnnotations(annotations :+ annot)

def withAnnotations[U >: Untyped <: T](annots: List[Tree[U]]): Modifiers[U] =
if (annots eq annotations) this
else copy(annotations = annots)

def withPrivateWithin(pw: TypeName) =
if (pw.isEmpty) this
else copy(privateWithin = pw)

def hasFlags = flags != EmptyFlags
def hasAnnotations = annotations.nonEmpty
def hasPrivateWithin = privateWithin != tpnme.EMPTY

def tokenPos: Seq[(Token, Position)] = ???
}

@sharable private var nextId = 0 // for debugging
@sharable private var nextId = 0 // for debugging

type LazyTree = AnyRef /* really: Tree | Lazy[Tree] */
type LazyTreeList = AnyRef /* really: List[Tree] | Lazy[List[Tree]] */
Expand Down Expand Up @@ -320,27 +276,41 @@ object Trees {
abstract class MemberDef[-T >: Untyped] extends NameTree[T] with DefTree[T] {
type ThisTree[-T >: Untyped] <: MemberDef[T]

private[this] var myMods: Modifiers[T] = null
private[this] var myMods: untpd.Modifiers = null

private[ast] def rawMods: Modifiers[T] =
if (myMods == null) genericEmptyModifiers else myMods
private[dotc] def rawMods: untpd.Modifiers =
if (myMods == null) untpd.EmptyModifiers else myMods

def rawComment: Option[Comment] = getAttachment(DocComment)

def withMods(mods: Modifiers[Untyped]): ThisTree[Untyped] = {
def withMods(mods: untpd.Modifiers): ThisTree[Untyped] = {
val tree = if (myMods == null || (myMods == mods)) this else clone.asInstanceOf[MemberDef[Untyped]]
tree.setMods(mods)
tree.asInstanceOf[ThisTree[Untyped]]
}

def withFlags(flags: FlagSet): ThisTree[Untyped] = withMods(Modifiers(flags))
def withFlags(flags: FlagSet): ThisTree[Untyped] = withMods(untpd.Modifiers(flags))

def setComment(comment: Option[Comment]): ThisTree[Untyped] = {
comment.map(putAttachment(DocComment, _))
asInstanceOf[ThisTree[Untyped]]
}

protected def setMods(mods: Modifiers[T @uncheckedVariance]) = myMods = mods
protected def setMods(mods: untpd.Modifiers) = myMods = mods

/** The position of the name defined by this definition.
* This is a point position if the definition is synthetic, or a range position
* if the definition comes from source.
* It might also be that the definition does not have a position (for instance when synthesized by
* a calling chain from `viewExists`), in that case the return position is NoPosition.
*/
def namePos =
if (pos.exists)
if (rawMods.is(Synthetic)) Position(pos.point, pos.point)
else Position(pos.point, pos.point + name.length, pos.point)
else pos


}

/** A ValDef or DefDef tree */
Expand Down Expand Up @@ -727,16 +697,14 @@ object Trees {
class EmptyValDef[T >: Untyped] extends ValDef[T](
nme.WILDCARD, genericEmptyTree[T], genericEmptyTree[T]) with WithoutTypeOrPos[T] {
override def isEmpty: Boolean = true
setMods(Modifiers[T](PrivateLocal))
setMods(untpd.Modifiers(PrivateLocal))
}

@sharable val theEmptyTree: Thicket[Type] = Thicket(Nil)
@sharable val theEmptyValDef = new EmptyValDef[Type]
@sharable val theEmptyModifiers = new Modifiers()

def genericEmptyValDef[T >: Untyped]: ValDef[T] = theEmptyValDef.asInstanceOf[ValDef[T]]
def genericEmptyTree[T >: Untyped]: Thicket[T] = theEmptyTree.asInstanceOf[Thicket[T]]
def genericEmptyModifiers[T >: Untyped]: Modifiers[T] = theEmptyModifiers.asInstanceOf[Modifiers[T]]

def flatten[T >: Untyped](trees: List[Tree[T]]): List[Tree[T]] = {
var buf: ListBuffer[Tree[T]] = null
Expand Down Expand Up @@ -795,7 +763,6 @@ object Trees {

abstract class Instance[T >: Untyped <: Type] extends DotClass { inst =>

type Modifiers = Trees.Modifiers[T]
type Tree = Trees.Tree[T]
type TypTree = Trees.TypTree[T]
type TermTree = Trees.TermTree[T]
Expand Down Expand Up @@ -853,14 +820,9 @@ object Trees {

@sharable val EmptyTree: Thicket = genericEmptyTree
@sharable val EmptyValDef: ValDef = genericEmptyValDef
@sharable val EmptyModifiers: Modifiers = genericEmptyModifiers

// ----- Auxiliary creation methods ------------------

def Modifiers(flags: FlagSet = EmptyFlags,
privateWithin: TypeName = tpnme.EMPTY,
annotations: List[Tree] = Nil) = new Modifiers(flags, privateWithin, annotations)

def Thicket(trees: List[Tree]): Thicket = new Thicket(trees)
def Thicket(): Thicket = EmptyTree
def Thicket(x1: Tree, x2: Tree): Thicket = Thicket(x1 :: x2 :: Nil)
Expand All @@ -870,11 +832,6 @@ object Trees {
case ys => Thicket(ys)
}

// ----- Accessing modifiers ----------------------------------------------------

abstract class ModsDeco { def mods: Modifiers }
implicit def modsDeco(mdef: MemberDef)(implicit ctx: Context): ModsDeco

// ----- Helper classes for copying, transforming, accumulating -----------------

val cpy: TreeCopier
Expand Down
9 changes: 0 additions & 9 deletions src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {

private def ta(implicit ctx: Context) = ctx.typeAssigner

def Modifiers(sym: Symbol)(implicit ctx: Context): Modifiers = Modifiers(
sym.flags & (if (sym.isType) ModifierFlags | VarianceFlags else ModifierFlags),
if (sym.privateWithin.exists) sym.privateWithin.asType.name else tpnme.EMPTY,
sym.annotations map (_.tree))

def Ident(tp: NamedType)(implicit ctx: Context): Ident =
ta.assignType(untpd.Ident(tp.name), tp)

Expand Down Expand Up @@ -446,10 +441,6 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
} else foldOver(sym, tree)
}

implicit class modsDeco(mdef: MemberDef)(implicit ctx: Context) extends ModsDeco {
def mods = if (mdef.hasType) Modifiers(mdef.symbol) else mdef.rawMods
}

override val cpy = new TypedTreeCopier

class TypedTreeCopier extends TreeCopier {
Expand Down
63 changes: 49 additions & 14 deletions src/dotty/tools/dotc/ast/untpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,52 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
*/
class InfixOpBlock(leftOperand: Tree, rightOp: Tree) extends Block(leftOperand :: Nil, rightOp)

// ----- Modifiers -----------------------------------------------------

/** Modifiers and annotations for definitions
* @param flags The set flags
* @param privateWithin If a private or protected has is followed by a
* qualifier [q], the name q, "" as a typename otherwise.
* @param annotations The annotations preceding the modifiers
*/
case class Modifiers (
flags: FlagSet = EmptyFlags,
privateWithin: TypeName = tpnme.EMPTY,
annotations: List[Tree] = Nil) extends Positioned with Cloneable {

def is(fs: FlagSet): Boolean = flags is fs
def is(fc: FlagConjunction): Boolean = flags is fc

def | (fs: FlagSet): Modifiers = withFlags(flags | fs)
def & (fs: FlagSet): Modifiers = withFlags(flags & fs)
def &~(fs: FlagSet): Modifiers = withFlags(flags &~ fs)

def toTypeFlags: Modifiers = withFlags(flags.toTypeFlags)
def toTermFlags: Modifiers = withFlags(flags.toTermFlags)

def withFlags(flags: FlagSet) =
if (this.flags == flags) this
else copy(flags = flags)

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

def withAnnotations(annots: List[Tree]): Modifiers =
if (annots eq annotations) this
else copy(annotations = annots)

def withPrivateWithin(pw: TypeName) =
if (pw.isEmpty) this
else copy(privateWithin = pw)

def hasFlags = flags != EmptyFlags
def hasAnnotations = annotations.nonEmpty
def hasPrivateWithin = privateWithin != tpnme.EMPTY
}

@sharable val EmptyModifiers: Modifiers = new Modifiers()

// ----- TypeTrees that refer to other tree's symbols -------------------

/** A type tree that gets its type from some other tree's symbol. Enters the
Expand Down Expand Up @@ -264,22 +310,11 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
/** A repeated argument such as `arg: _*` */
def repeated(arg: Tree)(implicit ctx: Context) = Typed(arg, Ident(tpnme.WILDCARD_STAR))

// ------- Decorators -------------------------------------------------
// ----- Accessing modifiers ----------------------------------------------------

implicit class UntypedTreeDecorator(val self: Tree) extends AnyVal {
def locateEnclosing(base: List[Tree], pos: Position): List[Tree] = {
def encloses(elem: Any) = elem match {
case t: Tree => t.pos contains pos
case _ => false
}
base.productIterator find encloses match {
case Some(tree: Tree) => locateEnclosing(tree :: base, pos)
case none => base
}
}
}
abstract class ModsDecorator { def mods: Modifiers }

implicit class modsDeco(val mdef: MemberDef)(implicit ctx: Context) extends ModsDeco {
implicit class modsDeco(val mdef: MemberDef)(implicit ctx: Context) {
def mods = mdef.rawMods
}

Expand Down
9 changes: 6 additions & 3 deletions src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -729,9 +729,12 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) {
}
}
val mods =
if (sym.annotations.isEmpty) EmptyModifiers
else Modifiers(annotations = sym.annotations.map(_.tree))
tree.withMods(mods) // record annotations in tree so that tree positions can be filled in.
if (sym.annotations.isEmpty) untpd.EmptyModifiers
else untpd.Modifiers(annotations = sym.annotations.map(_.tree))
tree.withMods(mods)
// record annotations in tree so that tree positions can be filled in.
// Note: Once the inline PR with its changes to positions is in, this should be
// no longer necessary.
goto(end)
setPos(start, tree)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import StdNames._, Denotations._, NameOps._, Flags._, Constants._, Annotations._
import dotty.tools.dotc.typer.ProtoTypes.{FunProtoTyped, FunProto}
import util.Positions._
import dotty.tools.dotc.ast.{tpd, Trees, untpd}, ast.tpd._
import ast.untpd.Modifiers
import printing.Texts._
import printing.Printer
import io.AbstractFile
Expand Down Expand Up @@ -1236,7 +1237,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
val pflags = (pflagsHi.toLong << 32) + pflagsLo
val flags = unpickleScalaFlags(pflags, isType)
val privateWithin = readNameRef().asTypeName
Trees.Modifiers[Type](flags, privateWithin, Nil)
Modifiers(flags, privateWithin, Nil)
}

protected def readTemplateRef()(implicit ctx: Context): Template =
Expand Down
11 changes: 9 additions & 2 deletions src/dotty/tools/dotc/printing/RefinedPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,15 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
import untpd.{modsDeco => _, _}

/** Print modifiers from symbols if tree has type, overriding the untpd behavior. */
implicit def modsDeco(mdef: untpd.MemberDef)(implicit ctx: Context): untpd.ModsDeco =
tpd.modsDeco(mdef.asInstanceOf[tpd.MemberDef]).asInstanceOf[untpd.ModsDeco]
implicit def modsDeco(mdef: untpd.MemberDef)(implicit ctx: Context): untpd.ModsDecorator =
new untpd.ModsDecorator {
def mods = if (mdef.hasType) Modifiers(mdef.symbol) else mdef.rawMods
}

def Modifiers(sym: Symbol)(implicit ctx: Context): Modifiers = untpd.Modifiers(
sym.flags & (if (sym.isType) ModifierFlags | VarianceFlags else ModifierFlags),
if (sym.privateWithin.exists) sym.privateWithin.asType.name else tpnme.EMPTY,
sym.annotations map (_.tree))

def isLocalThis(tree: Tree) = tree.typeOpt match {
case tp: ThisType => tp.cls == ctx.owner.enclosingClass
Expand Down
Loading