From 1bc50a7c84b0abc53299b3efcfec4f6a77c759e6 Mon Sep 17 00:00:00 2001 From: Miles Sabin Date: Fri, 2 Oct 2009 11:22:24 +0000 Subject: Patch from Mirko Stoker to add positions to Mod... Patch from Mirko Stoker to add positions to Modifiers. --- src/compiler/scala/tools/nsc/ast/Trees.scala | 16 +++--- .../scala/tools/nsc/ast/parser/Parsers.scala | 59 +++++++++++----------- .../scala/tools/nsc/javac/JavaParsers.scala | 2 +- .../scala/tools/nsc/symtab/classfile/Pickler.scala | 4 +- .../tools/nsc/symtab/classfile/UnPickler.scala | 2 +- .../scala/tools/nsc/typechecker/Namers.scala | 2 +- .../scala/tools/nsc/typechecker/Typers.scala | 2 +- 7 files changed, 44 insertions(+), 43 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 20464f2468..19e904700f 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -52,7 +52,7 @@ trait Trees { * Note: the typechecker drops these annotations, * use the AnnotationInfo's (Symbol.annotations) in later phases. */ - case class Modifiers(flags: Long, privateWithin: Name, annotations: List[Tree]) { + case class Modifiers(flags: Long, privateWithin: Name, annotations: List[Tree], positions: Map[Long, Position]) { def isCovariant = hasFlag(COVARIANT ) // marked with `+' def isContravariant = hasFlag(CONTRAVARIANT) // marked with `-' def isPrivate = hasFlag(PRIVATE ) @@ -73,24 +73,26 @@ trait Trees { def & (flag: Long): Modifiers = { val flags1 = flags & flag if (flags1 == flags) this - else Modifiers(flags1, privateWithin, annotations) + else Modifiers(flags1, privateWithin, annotations, positions) } def &~ (flag: Long): Modifiers = { val flags1 = flags & (~flag) if (flags1 == flags) this - else Modifiers(flags1, privateWithin, annotations) + else Modifiers(flags1, privateWithin, annotations, positions) } def | (flag: Long): Modifiers = { val flags1 = flags | flag if (flags1 == flags) this - else Modifiers(flags1, privateWithin, annotations) + else Modifiers(flags1, privateWithin, annotations, positions) } def withAnnotations(annots: List[Tree]) = if (annots.isEmpty) this - else Modifiers(flags, privateWithin, annotations ::: annots) + else Modifiers(flags, privateWithin, annotations ::: annots, positions) + def withPosition(flag: Long, position: Position) = + Modifiers(flags, privateWithin, annotations, positions + (flag -> position)) } - def Modifiers(flags: Long, privateWithin: Name): Modifiers = Modifiers(flags, privateWithin, List()) + def Modifiers(flags: Long, privateWithin: Name): Modifiers = Modifiers(flags, privateWithin, List(), new Map.EmptyMap) def Modifiers(flags: Long): Modifiers = Modifiers(flags, nme.EMPTY.toTypeName) val NoMods = Modifiers(0) @@ -1552,7 +1554,7 @@ trait Trees { else transform(stat)) filter (EmptyTree !=) def transformUnit(unit: CompilationUnit) { unit.body = transform(unit.body) } def transformModifiers(mods: Modifiers): Modifiers = - Modifiers(mods.flags, mods.privateWithin, transformTrees(mods.annotations)) + Modifiers(mods.flags, mods.privateWithin, transformTrees(mods.annotations), mods.positions) def atOwner[A](owner: Symbol)(trans: => A): A = { val prevOwner = currentOwner diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 1e118e38cc..9540351a65 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1549,12 +1549,14 @@ self => else mods - private def addMod(mods: Modifiers, mod: Long): Modifiers = { + private def addMod(mods: Modifiers, mod: Long, pos: Position): Modifiers = { if (mods hasFlag mod) syntaxError(in.offset, "repeated modifier", false) in.nextToken() - mods | mod + (mods | mod) withPosition (mod, pos) } + private def tokenRange(token: TokenData) = r2p(token.offset, token.offset, token.offset + token.name.length - 1) + /** AccessQualifier ::= "[" (Id | this) "]" */ def accessQualifierOpt(mods: Modifiers): Modifiers = { @@ -1588,21 +1590,21 @@ self => def modifiers(): Modifiers = normalize { def loop(mods: Modifiers): Modifiers = in.token match { case ABSTRACT => - loop(addMod(mods, Flags.ABSTRACT)) + loop(addMod(mods, Flags.ABSTRACT, tokenRange(in))) case FINAL => - loop(addMod(mods, Flags.FINAL)) + loop(addMod(mods, Flags.FINAL, tokenRange(in))) case SEALED => - loop(addMod(mods, Flags.SEALED)) + loop(addMod(mods, Flags.SEALED, tokenRange(in))) case PRIVATE => - loop(accessQualifierOpt(addMod(mods, Flags.PRIVATE))) + loop(accessQualifierOpt(addMod(mods, Flags.PRIVATE, tokenRange(in)))) case PROTECTED => - loop(accessQualifierOpt(addMod(mods, Flags.PROTECTED))) + loop(accessQualifierOpt(addMod(mods, Flags.PROTECTED, tokenRange(in)))) case OVERRIDE => - loop(addMod(mods, Flags.OVERRIDE)) + loop(addMod(mods, Flags.OVERRIDE, tokenRange(in))) case IMPLICIT => - loop(addMod(mods, Flags.IMPLICIT)) + loop(addMod(mods, Flags.IMPLICIT, tokenRange(in))) case LAZY => - loop(addMod(mods, Flags.LAZY)) + loop(addMod(mods, Flags.LAZY, tokenRange(in))) case NEWLINE => in.nextToken() loop(mods) @@ -1618,15 +1620,15 @@ self => def localModifiers(): Modifiers = { def loop(mods: Modifiers): Modifiers = in.token match { case ABSTRACT => - loop(addMod(mods, Flags.ABSTRACT)) + loop(addMod(mods, Flags.ABSTRACT, tokenRange(in))) case FINAL => - loop(addMod(mods, Flags.FINAL)) + loop(addMod(mods, Flags.FINAL, tokenRange(in))) case SEALED => - loop(addMod(mods, Flags.SEALED)) + loop(addMod(mods, Flags.SEALED, tokenRange(in))) case IMPLICIT => - loop(addMod(mods, Flags.IMPLICIT)) + loop(addMod(mods, Flags.IMPLICIT, tokenRange(in))) case LAZY => - loop(addMod(mods, Flags.LAZY)) + loop(addMod(mods, Flags.LAZY, tokenRange(in))) case _ => mods } @@ -1957,26 +1959,23 @@ self => syntaxError("lazy not allowed here. Only vals can be lazy", false) in.token match { case VAL => - patDefOrDcl(pos, mods) + patDefOrDcl(pos, mods withPosition(VAL, tokenRange(in))) case VAR => - patDefOrDcl(pos, mods | Flags.MUTABLE) + patDefOrDcl(pos, (mods | Flags.MUTABLE) withPosition (VAR, tokenRange(in))) case DEF => - List(funDefOrDcl(pos, mods)) + List(funDefOrDcl(pos, mods withPosition(DEF, tokenRange(in)))) case TYPE => - List(typeDefOrDcl(pos, mods)) + List(typeDefOrDcl(pos, mods withPosition(TYPE, tokenRange(in)))) case _ => List(tmplDef(pos, mods)) } } + private def caseAwareTokenOffset = if (in.token == CASECLASS || in.token == CASEOBJECT) in.prev.offset else in.offset + def nonLocalDefOrDcl : List[Tree] = { val annots = annotations(true, false) - val pos = - if (in.token == CASECLASS || in.token == CASEOBJECT) - in.prev.offset - else - in.offset - defOrDcl(pos, modifiers() withAnnotations annots) + defOrDcl(caseAwareTokenOffset, modifiers() withAnnotations annots) } /** PatDef ::= Pattern2 {`,' Pattern2} [`:' Type] `=' Expr @@ -2165,7 +2164,7 @@ self => /** Hook for IDE, for top-level classes/objects */ def topLevelTmplDef: Tree = { val annots = annotations(true, false) - val pos = in.offset + val pos = caseAwareTokenOffset val mods = modifiers() withAnnotations annots tmplDef(pos, mods) } @@ -2178,15 +2177,15 @@ self => if (mods.hasFlag(Flags.LAZY)) syntaxError("classes cannot be lazy", false) in.token match { case TRAIT => - classDef(pos, mods | Flags.TRAIT | Flags.ABSTRACT) + classDef(pos, (mods | Flags.TRAIT | Flags.ABSTRACT) withPosition (Flags.TRAIT, tokenRange(in))) case CLASS => classDef(pos, mods) case CASECLASS => - classDef(pos, mods | Flags.CASE) + classDef(pos, (mods | Flags.CASE) withPosition (Flags.CASE, tokenRange(in.prev /*scanner skips on 'case' to 'class', thus take prev*/))) case OBJECT => objectDef(pos, mods) case CASEOBJECT => - objectDef(pos, mods | Flags.CASE) + objectDef(pos, (mods | Flags.CASE) withPosition (Flags.CASE, tokenRange(in.prev /*scanner skips on 'case' to 'object', thus take prev*/))) case _ => syntaxErrorOrIncomplete("expected start of definition", true) EmptyTree @@ -2591,7 +2590,7 @@ self => } ts.toList } - val start = in.offset max 0 + val start = caseAwareTokenOffset max 0 topstats() match { case List(stat @ PackageDef(_, _)) => stat case stats => makePackaging(start, atPos(o2p(start)) { Ident(nme.EMPTY_PACKAGE_NAME) }, stats) diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala index ef4f7655b4..1406416f5f 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala @@ -543,7 +543,7 @@ trait JavaParsers extends JavaScanners { atPos(pos) { New(rootId(nme.AnnotationDefaultATTR.toTypeName), List(List())) } - mods1 = Modifiers(mods1.flags, mods1.privateWithin, annot :: mods1.annotations) + mods1 = Modifiers(mods1.flags, mods1.privateWithin, annot :: mods1.annotations, mods1.positions) skipTo(SEMI) accept(SEMI) blankExpr diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index 05ee731ca1..3ef8f38a9f 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -415,7 +415,7 @@ abstract class Pickler extends SubComponent { * argument of some Annotation */ private def putMods(mods: Modifiers) = if (putEntry(mods)) { // annotations in Modifiers are removed by the typechecker - val Modifiers(flags, privateWithin, Nil) = mods + val Modifiers(flags, privateWithin, Nil, _) = mods putEntry(privateWithin) } @@ -967,7 +967,7 @@ abstract class Pickler extends SubComponent { writeRefs(whereClauses) TREE - case Modifiers(flags, privateWithin, _) => + case Modifiers(flags, privateWithin, _, _) => val pflags = rawFlagsToPickled(flags) writeNat((pflags >> 32).toInt) writeNat((pflags & 0xFFFFFFFF).toInt) diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala index fccc5d7def..9dba9f9925 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala @@ -759,7 +759,7 @@ abstract class UnPickler { val pflags = (pflagsHi.toLong << 32) + pflagsLo val flags = pickledToRawFlags(pflags) val privateWithin = readNameRef() - Modifiers(flags, privateWithin, Nil) + Modifiers(flags, privateWithin, Nil, new Map.EmptyMap) } /* Read a reference to a pickled item */ diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index e84a1dd4d4..7a94f95d52 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -482,7 +482,7 @@ trait Namers { self: Analyzer => val getterName = if (hasBoolBP) "is" + beanName else "get" + beanName - val getterMods = Modifiers(flags, mods.privateWithin, Nil) + val getterMods = Modifiers(flags, mods.privateWithin, Nil, mods.positions) val beanGetterDef = atPos(vd.pos.focus) { DefDef(getterMods, getterName, Nil, List(Nil), tpt.duplicate, if (mods hasFlag DEFERRED) EmptyTree diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index c3fa5555c4..030028fcf6 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1425,7 +1425,7 @@ trait Typers { self: Analyzer => * into the symbol's ``annotations'' in the type completer / namer) */ def removeAnnotations(mods: Modifiers): Modifiers = - Modifiers(mods.flags, mods.privateWithin, Nil) + Modifiers(mods.flags, mods.privateWithin, Nil, mods.positions) /** * @param vdef ... -- cgit v1.2.3