aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/parsing/JavaParsers.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/parsing/JavaParsers.scala')
-rw-r--r--src/dotty/tools/dotc/parsing/JavaParsers.scala164
1 files changed, 88 insertions, 76 deletions
diff --git a/src/dotty/tools/dotc/parsing/JavaParsers.scala b/src/dotty/tools/dotc/parsing/JavaParsers.scala
index fbb362354..c00cd7c59 100644
--- a/src/dotty/tools/dotc/parsing/JavaParsers.scala
+++ b/src/dotty/tools/dotc/parsing/JavaParsers.scala
@@ -10,6 +10,7 @@ import scala.language.implicitConversions
import JavaTokens._
import JavaScanners._
+import Scanners.Offset
import Parsers._
import core._
import Contexts._
@@ -107,9 +108,6 @@ object JavaParsers {
def unimplementedExpr = Ident("???".toTermName)
- def makePackaging(pkg: RefTree, stats: List[Tree]): PackageDef =
- atPos(pkg.pos) { PackageDef(pkg, stats) }
-
def makeTemplate(parents: List[Tree], stats: List[Tree], tparams: List[TypeDef], needsDummyConstr: Boolean) = {
def pullOutFirstConstr(stats: List[Tree]): (Tree, List[Tree]) = stats match {
case (meth: DefDef) :: rest if meth.name == CONSTRUCTOR => (meth, rest)
@@ -250,14 +248,14 @@ object JavaParsers {
var t: RefTree = atPos(in.offset) { Ident(ident()) }
while (in.token == DOT) {
in.nextToken()
- t = atPos(in.offset) { Select(t, ident()) }
+ t = atPos(t.pos.start, in.offset) { Select(t, ident()) }
}
t
}
def optArrayBrackets(tpt: Tree): Tree =
if (in.token == LBRACKET) {
- val tpt1 = atPos(in.offset) { arrayOf(tpt) }
+ val tpt1 = atPos(tpt.pos.start, in.offset) { arrayOf(tpt) }
in.nextToken()
accept(RBRACKET)
optArrayBrackets(tpt1)
@@ -294,7 +292,7 @@ object JavaParsers {
}
while (in.token == DOT) {
in.nextToken()
- t = typeArgs(atPos(in.offset)(typeSelect(t, ident())))
+ t = typeArgs(atPos(t.pos.start, in.offset)(typeSelect(t, ident())))
}
convertToTypeId(t)
} else {
@@ -328,7 +326,7 @@ object JavaParsers {
val t1 = convertToTypeId(t)
val args = repsep(typeArg, COMMA)
acceptClosingAngle()
- atPos(t1.pos) {
+ atPos(t1.pos.start) {
AppliedTypeTree(t1, args)
}
} else t
@@ -356,7 +354,11 @@ object JavaParsers {
// assumed true unless we see public/private/protected
var isPackageAccess = true
var annots: List[Tree] = Nil
- def addAnnot(sym: ClassSymbol) = annots :+= New(TypeTree(sym.typeRef)).withPos(Position(in.offset))
+ def addAnnot(sym: ClassSymbol) =
+ annots :+= atPos(in.offset) {
+ in.nextToken()
+ New(TypeTree(sym.typeRef))
+ }
while (true) {
in.token match {
@@ -387,13 +389,10 @@ object JavaParsers {
in.nextToken()
case NATIVE =>
addAnnot(NativeAnnot)
- in.nextToken()
case TRANSIENT =>
addAnnot(TransientAnnot)
- in.nextToken()
case VOLATILE =>
addAnnot(VolatileAnnot)
- in.nextToken()
case SYNCHRONIZED | STRICTFP =>
in.nextToken()
case _ =>
@@ -443,16 +442,19 @@ object JavaParsers {
}
def formalParam(): ValDef = {
+ val start = in.offset
if (in.token == FINAL) in.nextToken()
annotations()
var t = typ()
if (in.token == DOTDOTDOT) {
in.nextToken()
- t = atPos(t.pos) {
+ t = atPos(t.pos.start) {
PostfixOp(t, nme.raw.STAR)
}
}
- varDecl(Position(in.offset), Modifiers(Flags.JavaDefined | Flags.Param), t, ident().toTermName)
+ atPos(start, in.offset) {
+ varDecl(Modifiers(Flags.JavaDefined | Flags.Param), t, ident().toTermName)
+ }
}
def optThrows(): Unit = {
@@ -462,7 +464,7 @@ object JavaParsers {
}
}
- def methodBody(): Tree = {
+ def methodBody(): Tree = atPos(in.offset) {
skipAhead()
accept(RBRACE) // skip block
unimplementedExpr
@@ -470,16 +472,18 @@ object JavaParsers {
def definesInterface(token: Int) = token == INTERFACE || token == AT
- def termDecl(mods: Modifiers, parentToken: Int, parentTParams: List[TypeDef]): List[Tree] = {
+ def termDecl(start: Offset, mods: Modifiers, parentToken: Int, parentTParams: List[TypeDef]): List[Tree] = {
val inInterface = definesInterface(parentToken)
val tparams = if (in.token == LT) typeParams(Flags.JavaDefined | Flags.Param) else List()
val isVoid = in.token == VOID
var rtpt =
- if (isVoid) {
- in.nextToken()
- TypeTree(UnitType) withPos Position(in.offset)
- } else typ()
- var offset = in.offset
+ if (isVoid)
+ atPos(in.offset) {
+ in.nextToken()
+ TypeTree(UnitType)
+ }
+ else typ()
+ var nameOffset = in.offset
val rtptName = rtpt match {
case Ident(name) => name
case _ => nme.EMPTY
@@ -489,14 +493,15 @@ object JavaParsers {
val vparams = formalParams()
optThrows()
List {
- atPos(offset) {
- DefDef(nme.CONSTRUCTOR, parentTParams, List(vparams), TypeTree(), methodBody()).withMods(mods)
+ atPos(start) {
+ DefDef(nme.CONSTRUCTOR, parentTParams,
+ List(vparams), TypeTree(), methodBody()).withMods(mods)
}
}
} else {
var mods1 = mods
if (mods is Flags.Abstract) mods1 = mods &~ Flags.Abstract
- offset = in.offset
+ nameOffset = in.offset
val name = ident()
if (in.token == LPAREN) {
// method declaration
@@ -510,13 +515,14 @@ object JavaParsers {
} else {
if (parentToken == AT && in.token == DEFAULT) {
val annot =
- atPos(offset) {
+ atPos(nameOffset) {
New(Select(scalaDot(nme.runtime), tpnme.AnnotationDefaultATTR), Nil)
}
mods1 = mods1 withAddedAnnotation annot
+ val unimplemented = unimplementedExpr
skipTo(SEMI)
accept(SEMI)
- unimplementedExpr
+ unimplemented
} else {
accept(SEMI)
EmptyTree
@@ -524,13 +530,13 @@ object JavaParsers {
}
//if (inInterface) mods1 |= Flags.Deferred
List {
- atPos(offset) {
+ atPos(start, nameOffset) {
DefDef(name.toTermName, tparams, List(vparams), rtpt, body).withMods(mods1 | Flags.Method)
}
}
} else {
if (inInterface) mods1 |= Flags.Final | Flags.JavaStatic
- val result = fieldDecls(Position(offset), mods1, rtpt, name)
+ val result = fieldDecls(start, nameOffset, mods1, rtpt, name)
accept(SEMI)
result
}
@@ -546,19 +552,21 @@ object JavaParsers {
* Once we have reached the end of the statement, we know whether
* these potential definitions are real or not.
*/
- def fieldDecls(pos: Position, mods: Modifiers, tpt: Tree, name: Name): List[Tree] = {
- val buf = ListBuffer[Tree](varDecl(pos, mods, tpt, name.toTermName))
+ def fieldDecls(start: Offset, firstNameOffset: Offset, mods: Modifiers, tpt: Tree, name: Name): List[Tree] = {
+ val buf = ListBuffer[Tree](
+ atPos(start, firstNameOffset) { varDecl(mods, tpt, name.toTermName) })
val maybe = new ListBuffer[Tree] // potential variable definitions.
while (in.token == COMMA) {
in.nextToken()
if (in.token == IDENTIFIER) { // if there's an ident after the comma ...
+ val nextNameOffset = in.offset
val name = ident()
if (in.token == EQUALS || in.token == SEMI) { // ... followed by a `=` or `;`, we know it's a real variable definition
buf ++= maybe
- buf += varDecl(Position(in.offset), mods, tpt, name.toTermName)
+ buf += atPos(start, nextNameOffset) { varDecl(mods, tpt, name.toTermName) }
maybe.clear()
} else if (in.token == COMMA) { // ... if there's a comma after the ident, it could be a real vardef or not.
- maybe += varDecl(Position(in.offset), mods, tpt, name.toTermName)
+ maybe += atPos(start, nextNameOffset) { varDecl(mods, tpt, name.toTermName) }
} else { // ... if there's something else we were still in the initializer of the
// previous var def; skip to next comma or semicolon.
skipTo(COMMA, SEMI)
@@ -576,35 +584,32 @@ object JavaParsers {
buf.toList
}
- def varDecl(pos: Position, mods: Modifiers, tpt: Tree, name: TermName): ValDef = {
+ def varDecl(mods: Modifiers, tpt: Tree, name: TermName): ValDef = {
val tpt1 = optArrayBrackets(tpt)
if (in.token == EQUALS && !(mods is Flags.Param)) skipTo(COMMA, SEMI)
val mods1 = if (mods is Flags.Final) mods else mods | Flags.Mutable
- atPos(pos) {
- ValDef(name, tpt1, if (mods is Flags.Param) EmptyTree else unimplementedExpr).withMods(mods1)
- }
+ ValDef(name, tpt1, if (mods is Flags.Param) EmptyTree else unimplementedExpr).withMods(mods1)
}
- def memberDecl(mods: Modifiers, parentToken: Int, parentTParams: List[TypeDef]): List[Tree] = in.token match {
+ def memberDecl(start: Offset, mods: Modifiers, parentToken: Int, parentTParams: List[TypeDef]): List[Tree] = in.token match {
case CLASS | ENUM | INTERFACE | AT =>
- typeDecl(if (definesInterface(parentToken)) mods | Flags.JavaStatic else mods)
+ typeDecl(start, if (definesInterface(parentToken)) mods | Flags.JavaStatic else mods)
case _ =>
- termDecl(mods, parentToken, parentTParams)
+ termDecl(start, mods, parentToken, parentTParams)
}
def makeCompanionObject(cdef: TypeDef, statics: List[Tree]): Tree =
atPos(cdef.pos) {
+ assert(cdef.pos.exists)
ModuleDef(cdef.name.toTermName,
makeTemplate(List(), statics, List(), false)).withMods((cdef.mods & (Flags.AccessFlags | Flags.JavaDefined)).toTermFlags)
}
- private val wild = Ident(nme.WILDCARD) withPos Position(-1)
- private val wildList = List(wild) // OPT This list is shared for performance.
+ private def wild = Ident(nme.WILDCARD)
+ private def wildList = List(wild) // OPT This list is shared for performance.
def importCompanionObject(cdef: TypeDef): Tree =
- atPos(cdef.pos) {
- Import(Ident(cdef.name.toTermName), wildList)
- }
+ Import(Ident(cdef.name.toTermName).withPos(NoPosition), wildList)
// Importing the companion object members cannot be done uncritically: see
// ticket #2377 wherein a class contains two static inner classes, each of which
@@ -633,8 +638,8 @@ object JavaParsers {
}
def importDecl(): List[Tree] = {
+ val start = in.offset
accept(IMPORT)
- val offset = in.offset
val buf = new ListBuffer[Name]
def collectIdents() : Int = {
if (in.token == ASTERISK) {
@@ -657,7 +662,7 @@ object JavaParsers {
accept(SEMI)
val names = buf.toList
if (names.length < 2) {
- syntaxError(offset, "illegal import", skipIt = false)
+ syntaxError(start, "illegal import", skipIt = false)
List()
} else {
val qual = ((Ident(names.head): Tree) /: names.tail.init) (Select(_, _))
@@ -667,7 +672,8 @@ object JavaParsers {
// case nme.WILDCARD => Pair(ident, Ident(null) withPos Position(-1))
// case _ => Pair(ident, ident)
// }
- List(atPos(offset)(Import(qual, List(ident))))
+ val imp = atPos(start) { Import(qual, List(ident)) }
+ imp :: Nil
}
}
@@ -679,9 +685,9 @@ object JavaParsers {
List()
}
- def classDecl(mods: Modifiers): List[Tree] = {
+ def classDecl(start: Offset, mods: Modifiers): List[Tree] = {
accept(CLASS)
- val offset = in.offset
+ val nameOffset = in.offset
val name = identForType()
val tparams = typeParams()
val superclass =
@@ -693,14 +699,15 @@ object JavaParsers {
}
val interfaces = interfacesOpt()
val (statics, body) = typeBody(CLASS, name, tparams)
- addCompanionObject(statics, atPos(offset) {
+ val cls = atPos(start, nameOffset) {
TypeDef(name, makeTemplate(superclass :: interfaces, body, tparams, true)).withMods(mods)
- })
+ }
+ addCompanionObject(statics, cls)
}
- def interfaceDecl(mods: Modifiers): List[Tree] = {
+ def interfaceDecl(start: Offset, mods: Modifiers): List[Tree] = {
accept(INTERFACE)
- val offset = in.offset
+ val nameOffset = in.offset
val name = identForType()
val tparams = typeParams()
val parents =
@@ -711,11 +718,12 @@ object JavaParsers {
List(javaLangObject())
}
val (statics, body) = typeBody(INTERFACE, name, tparams)
- addCompanionObject(statics, atPos(offset) {
+ val iface = atPos(start, nameOffset) {
TypeDef(
name, tparams,
makeTemplate(parents, body, tparams, false)).withMods(mods | Flags.Trait | Flags.JavaInterface | Flags.Abstract)
- })
+ }
+ addCompanionObject(statics, iface)
}
def typeBody(leadingToken: Int, parentName: Name, parentTParams: List[TypeDef]): (List[Tree], List[Tree]) = {
@@ -730,7 +738,8 @@ object JavaParsers {
val statics = new ListBuffer[Tree]
val members = new ListBuffer[Tree]
while (in.token != RBRACE && in.token != EOF) {
- var mods = modifiers(inInterface)
+ val start = in.offset
+ var mods = atPos(start) { modifiers(inInterface) }
if (in.token == LBRACE) {
skipAhead() // skip init block, we just assume we have seen only static
accept(RBRACE)
@@ -738,7 +747,7 @@ object JavaParsers {
in.nextToken()
} else {
if (in.token == ENUM || definesInterface(in.token)) mods |= Flags.JavaStatic
- val decls = memberDecl(mods, parentToken, parentTParams)
+ val decls = memberDecl(start, mods, parentToken, parentTParams)
(if ((mods is Flags.JavaStatic) || inInterface && !(decls exists (_.isInstanceOf[DefDef])))
statics
else
@@ -761,10 +770,10 @@ object JavaParsers {
Select(javaLangDot(nme.annotation), tpnme.Annotation),
scalaAnnotationDot(tpnme.ClassfileAnnotation)
)
- def annotationDecl(mods: Modifiers): List[Tree] = {
+ def annotationDecl(start: Offset, mods: Modifiers): List[Tree] = {
accept(AT)
accept(INTERFACE)
- val offset = in.offset
+ val nameOffset = in.offset
val name = identForType()
val (statics, body) = typeBody(AT, name, List())
val constructorParams = body.collect {
@@ -774,14 +783,15 @@ object JavaParsers {
List(), List(constructorParams), TypeTree(), EmptyTree).withMods(Modifiers(Flags.JavaDefined))
val body1 = body.filterNot(_.isInstanceOf[DefDef])
val templ = makeTemplate(annotationParents, constr :: body1, List(), false)
- addCompanionObject(statics, atPos(offset) {
+ val annot = atPos(start, nameOffset) {
TypeDef(name, templ).withMods(mods | Flags.Abstract)
- })
+ }
+ addCompanionObject(statics, annot)
}
- def enumDecl(mods: Modifiers): List[Tree] = {
+ def enumDecl(start: Offset, mods: Modifiers): List[Tree] = {
accept(ENUM)
- val offset = in.offset
+ val nameOffset = in.offset
val name = identForType()
def enumType = Ident(name)
val interfaces = interfacesOpt()
@@ -824,10 +834,11 @@ object JavaParsers {
val superclazz = Apply(TypeApply(
Select(New(javaLangDot(tpnme.Enum)), nme.CONSTRUCTOR), List(enumType)),
List(Literal(Constant(null)),Literal(Constant(0))))
- addCompanionObject(consts ::: statics ::: predefs, atPos(offset) {
+ val enum = atPos(start, nameOffset) {
TypeDef(name, List(),
makeTemplate(superclazz :: interfaces, body, List(), true)).withMods(mods | Flags.Enum)
- })
+ }
+ addCompanionObject(consts ::: statics ::: predefs, enum)
}
def enumConst(enumType: Tree) = {
@@ -848,22 +859,21 @@ object JavaParsers {
}
}
- def typeDecl(mods: Modifiers): List[Tree] = in.token match {
- case ENUM => enumDecl(mods)
- case INTERFACE => interfaceDecl(mods)
- case AT => annotationDecl(mods)
- case CLASS => classDecl(mods)
+ def typeDecl(start: Offset, mods: Modifiers): List[Tree] = in.token match {
+ case ENUM => enumDecl(start, mods)
+ case INTERFACE => interfaceDecl(start, mods)
+ case AT => annotationDecl(start, mods)
+ case CLASS => classDecl(start, mods)
case _ => in.nextToken(); syntaxError("illegal start of type declaration", skipIt = true); List(errorTypeTree)
}
/** CompilationUnit ::= [package QualId semi] TopStatSeq
*/
def compilationUnit(): Tree = {
- var offset = in.offset
+ val start = in.offset
val pkg: RefTree =
if (in.token == AT || in.token == PACKAGE) {
annotations()
- offset = in.offset
accept(PACKAGE)
val pkg = qualId()
accept(SEMI)
@@ -880,13 +890,15 @@ object JavaParsers {
buf ++= importDecl()
while (in.token != EOF && in.token != RBRACE) {
while (in.token == SEMI) in.nextToken()
- if (in.token != EOF)
- buf ++= typeDecl(modifiers(inInterface = false))
+ if (in.token != EOF) {
+ val start = in.offset
+ val mods = atPos(start) { modifiers(inInterface = false) }
+ buf ++= typeDecl(start, mods)
+ }
}
+ val unit = atPos(start) { PackageDef(pkg, buf.toList) }
accept(EOF)
- atPos(offset) {
- makePackaging(pkg, buf.toList)
- }
+ unit
}
}
}