aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorliu fengyun <liu@fengy.me>2016-10-18 16:33:50 +0200
committerliu fengyun <liu@fengy.me>2016-10-22 11:02:52 +0200
commit26329529e12b8cd9c66427f13445ce3ca1ab4015 (patch)
treece02786f58e12ccd54e5ec368af83328231831ef /src
parent0e3b4aaac845a88abad12e75ca0421a66752dd61 (diff)
downloaddotty-26329529e12b8cd9c66427f13445ce3ca1ab4015.tar.gz
dotty-26329529e12b8cd9c66427f13445ce3ca1ab4015.tar.bz2
dotty-26329529e12b8cd9c66427f13445ce3ca1ab4015.zip
Record syntactic information about modifiers
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/ast/untpd.scala50
-rw-r--r--src/dotty/tools/dotc/parsing/Parsers.scala34
2 files changed, 70 insertions, 14 deletions
diff --git a/src/dotty/tools/dotc/ast/untpd.scala b/src/dotty/tools/dotc/ast/untpd.scala
index 852c3a346..3ffc47bf8 100644
--- a/src/dotty/tools/dotc/ast/untpd.scala
+++ b/src/dotty/tools/dotc/ast/untpd.scala
@@ -94,9 +94,42 @@ 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
@@ -104,7 +137,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
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
@@ -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)
diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala
index 80c8f7b15..574a4d4fc 100644
--- a/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -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 =
@@ -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
}
@@ -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
@@ -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")