Skip to content

Commit

Permalink
Record syntactic information about modifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
liufengyun committed Oct 22, 2016
1 parent 0e3b4aa commit 2632952
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 14 deletions.
50 changes: 46 additions & 4 deletions src/dotty/tools/dotc/ast/untpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -94,17 +94,51 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
class InfixOpBlock(leftOperand: Tree, rightOp: Tree) extends Block(leftOperand :: Nil, rightOp)

// ----- Modifiers -----------------------------------------------------
/** Mod is intended to record syntactic information about modifiers, it's
* NOT a replacement of flagsets.
*
* For any query about semantic information, check `flags` instead.
*/
sealed trait Mod extends Positioned

/** Modifiers and annotations for definitions
* @param flags The set flags
object Mod {
case class Private() extends Mod

case class Protected() extends Mod

case class Val() extends Mod

case class Var() extends Mod

case class Implicit() extends Mod

case class Final() extends Mod

case class Sealed() extends Mod

case class Override() extends Mod

case class Abstract() extends Mod

case class Lazy() extends Mod

case class Inline() extends Mod

case class Type() extends Mod
}

/** 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 {
annotations: List[Tree] = Nil,
mods: List[Mod] = Nil) extends Positioned with Cloneable {

def is(fs: FlagSet): Boolean = flags is fs
def is(fc: FlagConjunction): Boolean = flags is fc
Expand All @@ -120,7 +154,15 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
if (this.flags == flags) this
else copy(flags = flags)

def withAddedAnnotation(annot: Tree): Modifiers =
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)

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

Expand Down
34 changes: 24 additions & 10 deletions src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1476,7 +1476,19 @@ object Parsers {
case SEALED => Sealed
}

/** Drop `private' modifier when followed by a qualifier.
private def modOfToken(tok: Int): Mod = tok match {
case ABSTRACT => Mod.Abstract()
case FINAL => Mod.Final()
case IMPLICIT => Mod.Implicit()
case INLINE => Mod.Inline()
case LAZY => Mod.Lazy()
case OVERRIDE => Mod.Override()
case PRIVATE => Mod.Private()
case PROTECTED => Mod.Protected()
case SEALED => Mod.Sealed()
}

/** Drop `private' modifier when followed by a qualifier.
* Contract `abstract' and `override' to ABSOVERRIDE
*/
private def normalize(mods: Modifiers): Modifiers =
Expand All @@ -1488,10 +1500,12 @@ object Parsers {
mods

private def addModifier(mods: Modifiers): Modifiers = {
val flag = flagOfToken(in.token)
val tok = in.token
val flag = flagOfToken(tok)
val mod = atPos(in.offset) { in.nextToken(); modOfToken(tok) }

if (mods is flag) syntaxError(RepeatedModifier(flag.toString))
val res = addFlag(mods, flag)
in.nextToken()
val res = addFlag(mods, flag).withAddedMod(mod)
res
}

Expand Down Expand Up @@ -1614,8 +1628,8 @@ object Parsers {
mods =
atPos(start, in.offset) {
if (in.token == TYPE) {
in.nextToken()
mods | Param | ParamAccessor
val mod = atPos(in.offset) { in.nextToken(); Mod.Type() }
(mods | Param | ParamAccessor).withAddedMod(mod)
} else {
if (mods.hasFlags) syntaxError("`type' expected")
mods | Param | PrivateLocal
Expand Down Expand Up @@ -1670,11 +1684,11 @@ object Parsers {
mods =
atPos(start, in.offset) {
if (in.token == VAL) {
in.nextToken()
mods
val mod = atPos(in.offset) { in.nextToken(); Mod.Val() }
mods.withAddedMod(mod)
} else if (in.token == VAR) {
in.nextToken()
addFlag(mods, Mutable)
val mod = atPos(in.offset) { in.nextToken(); Mod.Var() }
addFlag(mods, Mutable).withAddedMod(mod)
} else {
if (!(mods.flags &~ (ParamAccessor | Inline)).isEmpty)
syntaxError("`val' or `var' expected")
Expand Down

0 comments on commit 2632952

Please sign in to comment.