aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/src/dotty/tools/dotc/parsing/Parsers.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/Parsers.scala71
1 files changed, 40 insertions, 31 deletions
diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
index fa0576c7a..838f7514c 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -83,6 +83,14 @@ object Parsers {
def atPos[T <: Positioned](start: Offset)(t: T): T =
atPos(start, start)(t)
+ /** Defensive version of Position#start */
+ def startPos(t: Positioned): Int =
+ if (t.pos.exists) t.pos.start else in.offset
+
+ /** Defensive version of Position#end */
+ def endPos(t: Positioned): Int =
+ if (t.pos.exists) t.pos.end else in.lastOffset
+
def nameStart: Offset =
if (in.token == BACKQUOTED_IDENT) in.offset + 1 else in.offset
@@ -448,7 +456,7 @@ object Parsers {
val topInfo = opStack.head
opStack = opStack.tail
val od = reduceStack(base, topInfo.operand, 0, true)
- return atPos(od.pos.start, topInfo.offset) {
+ return atPos(startPos(od), topInfo.offset) {
PostfixOp(od, topInfo.operator)
}
}
@@ -492,7 +500,7 @@ object Parsers {
/** Accept identifier acting as a selector on given tree `t`. */
def selector(t: Tree): Tree =
- atPos(t.pos.start, in.offset) { Select(t, ident()) }
+ atPos(startPos(t), in.offset) { Select(t, ident()) }
/** Selectors ::= ident { `.' ident()
*
@@ -728,7 +736,7 @@ object Parsers {
def refinedTypeRest(t: Tree): Tree = {
newLineOptWhenFollowedBy(LBRACE)
- if (in.token == LBRACE) refinedTypeRest(atPos(t.pos.start) { RefinedTypeTree(t, refinement()) })
+ if (in.token == LBRACE) refinedTypeRest(atPos(startPos(t)) { RefinedTypeTree(t, refinement()) })
else t
}
@@ -749,7 +757,7 @@ object Parsers {
def annotType(): Tree = annotTypeRest(simpleType())
def annotTypeRest(t: Tree): Tree =
- if (in.token == AT) annotTypeRest(atPos(t.pos.start) { Annotated(t, annot()) })
+ if (in.token == AT) annotTypeRest(atPos(startPos(t)) { Annotated(t, annot()) })
else t
/** SimpleType ::= SimpleType TypeArgs
@@ -780,19 +788,19 @@ object Parsers {
val handleSingletonType: Tree => Tree = t =>
if (in.token == TYPE) {
in.nextToken()
- atPos(t.pos.start) { SingletonTypeTree(t) }
+ atPos(startPos(t)) { SingletonTypeTree(t) }
} else t
private def simpleTypeRest(t: Tree): Tree = in.token match {
case HASH => simpleTypeRest(typeProjection(t))
- case LBRACKET => simpleTypeRest(atPos(t.pos.start) { AppliedTypeTree(t, typeArgs(namedOK = true)) })
+ case LBRACKET => simpleTypeRest(atPos(startPos(t)) { AppliedTypeTree(t, typeArgs(namedOK = true)) })
case _ => t
}
private def typeProjection(t: Tree): Tree = {
accept(HASH)
val id = typeIdent()
- atPos(t.pos.start, id.pos.start) { Select(t, id.name) }
+ atPos(startPos(t), startPos(id)) { Select(t, id.name) }
}
/** NamedTypeArg ::= id `=' Type
@@ -846,7 +854,7 @@ object Parsers {
val t = toplevelTyp()
if (isIdent(nme.raw.STAR)) {
in.nextToken()
- atPos(t.pos.start) { PostfixOp(t, nme.raw.STAR) }
+ atPos(startPos(t)) { PostfixOp(t, nme.raw.STAR) }
} else t
}
@@ -971,7 +979,7 @@ object Parsers {
val t = expr1(location)
if (in.token == ARROW) {
placeholderParams = saved
- closureRest(t.pos.start, location, convertToParams(t))
+ closureRest(startPos(t), location, convertToParams(t))
}
else if (isWildcard(t)) {
placeholderParams = placeholderParams ::: saved
@@ -1025,7 +1033,7 @@ object Parsers {
assert(handlerStart != -1)
syntaxError(
new EmptyCatchBlock(body),
- Position(handlerStart, handler.pos.end)
+ Position(handlerStart, endPos(handler))
)
case _ =>
}
@@ -1035,7 +1043,7 @@ object Parsers {
else {
if (handler.isEmpty) warning(
EmptyCatchAndFinallyBlock(body),
- source atPos Position(tryOffset, body.pos.end)
+ source atPos Position(tryOffset, endPos(body))
)
EmptyTree
}
@@ -1057,21 +1065,21 @@ object Parsers {
case EQUALS =>
t match {
case Ident(_) | Select(_, _) | Apply(_, _) =>
- atPos(t.pos.start, in.skipToken()) { Assign(t, expr()) }
+ atPos(startPos(t), in.skipToken()) { Assign(t, expr()) }
case _ =>
t
}
case COLON =>
ascription(t, location)
case MATCH =>
- atPos(t.pos.start, in.skipToken()) {
+ atPos(startPos(t), in.skipToken()) {
inBraces(Match(t, caseClauses()))
}
case _ =>
t
}
- def ascription(t: Tree, location: Location.Value) = atPos(t.pos.start, in.skipToken()) {
+ def ascription(t: Tree, location: Location.Value) = atPos(startPos(t), in.skipToken()) {
in.token match {
case USCORE =>
val uscoreStart = in.skipToken()
@@ -1105,7 +1113,7 @@ object Parsers {
val id = termIdent()
val paramExpr =
if (location == Location.InBlock && in.token == COLON)
- atPos(id.pos.start, in.skipToken()) { Typed(id, infixType()) }
+ atPos(startPos(id), in.skipToken()) { Typed(id, infixType()) }
else
id
closureRest(start, location, convertToParam(paramExpr, mods) :: Nil)
@@ -1194,13 +1202,13 @@ object Parsers {
in.nextToken()
simpleExprRest(selector(t), canApply = true)
case LBRACKET =>
- val tapp = atPos(t.pos.start, in.offset) { TypeApply(t, typeArgs(namedOK = true)) }
+ val tapp = atPos(startPos(t), in.offset) { TypeApply(t, typeArgs(namedOK = true)) }
simpleExprRest(tapp, canApply = true)
case LPAREN | LBRACE if canApply =>
- val app = atPos(t.pos.start, in.offset) { Apply(t, argumentExprs()) }
+ val app = atPos(startPos(t), in.offset) { Apply(t, argumentExprs()) }
simpleExprRest(app, canApply = true)
case USCORE =>
- atPos(t.pos.start, in.skipToken()) { PostfixOp(t, nme.WILDCARD) }
+ atPos(startPos(t), in.skipToken()) { PostfixOp(t, nme.WILDCARD) }
case _ =>
t
}
@@ -1284,7 +1292,7 @@ object Parsers {
if (in.token == IF) guard()
else {
val pat = pattern1()
- if (in.token == EQUALS) atPos(pat.pos.start, in.skipToken()) { GenAlias(pat, expr()) }
+ if (in.token == EQUALS) atPos(startPos(pat), in.skipToken()) { GenAlias(pat, expr()) }
else generatorRest(pat)
}
@@ -1293,7 +1301,7 @@ object Parsers {
def generator(): Tree = generatorRest(pattern1())
def generatorRest(pat: Tree) =
- atPos(pat.pos.start, accept(LARROW)) { GenFrom(pat, expr()) }
+ atPos(startPos(pat), accept(LARROW)) { GenFrom(pat, expr()) }
/** ForExpr ::= `for' (`(' Enumerators `)' | `{' Enumerators `}')
* {nl} [`yield'] Expr
@@ -1357,7 +1365,7 @@ object Parsers {
val pattern = () => {
val pat = pattern1()
if (isIdent(nme.raw.BAR))
- atPos(pat.pos.start) { Alternative(pat :: patternAlts()) }
+ atPos(startPos(pat)) { Alternative(pat :: patternAlts()) }
else pat
}
@@ -1383,15 +1391,15 @@ object Parsers {
// compatibility for Scala2 `x @ _*` syntax
infixPattern() match {
case pt @ Ident(tpnme.WILDCARD_STAR) =>
- migrationWarningOrError("The syntax `x @ _*' is no longer supported; use `x : _*' instead", p.pos.start)
- atPos(p.pos.start, offset) { Typed(p, pt) }
+ migrationWarningOrError("The syntax `x @ _*' is no longer supported; use `x : _*' instead", startPos(p))
+ atPos(startPos(p), offset) { Typed(p, pt) }
case p =>
- atPos(p.pos.start, offset) { Bind(name, p) }
+ atPos(startPos(p), offset) { Bind(name, p) }
}
case p @ Ident(tpnme.WILDCARD_STAR) =>
// compatibility for Scala2 `_*` syntax
- migrationWarningOrError("The syntax `_*' is no longer supported; use `x : _*' instead", p.pos.start)
- atPos(p.pos.start) { Typed(Ident(nme.WILDCARD), p) }
+ migrationWarningOrError("The syntax `_*' is no longer supported; use `x : _*' instead", startPos(p))
+ atPos(startPos(p)) { Typed(Ident(nme.WILDCARD), p) }
case p =>
p
}
@@ -1415,7 +1423,7 @@ object Parsers {
val simplePattern = () => in.token match {
case IDENTIFIER | BACKQUOTED_IDENT | THIS =>
path(thisOK = true) match {
- case id @ Ident(nme.raw.MINUS) if isNumericLit => literal(id.pos.start)
+ case id @ Ident(nme.raw.MINUS) if isNumericLit => literal(startPos(id))
case t => simplePatternRest(t)
}
case USCORE =>
@@ -1445,9 +1453,9 @@ object Parsers {
def simplePatternRest(t: Tree): Tree = {
var p = t
if (in.token == LBRACKET)
- p = atPos(t.pos.start, in.offset) { TypeApply(p, typeArgs()) }
+ p = atPos(startPos(t), in.offset) { TypeApply(p, typeArgs()) }
if (in.token == LPAREN)
- p = atPos(t.pos.start, in.offset) { Apply(p, argumentPatterns()) }
+ p = atPos(startPos(t), in.offset) { Apply(p, argumentPatterns()) }
p
}
@@ -1573,7 +1581,8 @@ object Parsers {
case Select(qual, name) => cpy.Select(tree)(adjustStart(start)(qual), name)
case _ => tree
}
- if (start < tree1.pos.start) tree1.withPos(tree1.pos.withStart(start))
+ if (tree1.pos.exists && start < tree1.pos.start)
+ tree1.withPos(tree1.pos.withStart(start))
else tree1
}
@@ -1804,7 +1813,7 @@ object Parsers {
def importSelector(): Tree = {
val from = termIdentOrWildcard()
if (from.name != nme.WILDCARD && in.token == ARROW)
- atPos(from.pos.start, in.skipToken()) {
+ atPos(startPos(from), in.skipToken()) {
Thicket(from, termIdentOrWildcard())
}
else from