@@ -83,6 +83,14 @@ object Parsers {
83
83
def atPos [T <: Positioned ](start : Offset )(t : T ): T =
84
84
atPos(start, start)(t)
85
85
86
+ /** Defensive version of Position#start */
87
+ def startPos (t : Positioned ): Int =
88
+ if (t.pos.exists) t.pos.start else in.offset
89
+
90
+ /** Defensive version of Position#end */
91
+ def endPos (t : Positioned ): Int =
92
+ if (t.pos.exists) t.pos.end else in.lastOffset
93
+
86
94
def nameStart : Offset =
87
95
if (in.token == BACKQUOTED_IDENT ) in.offset + 1 else in.offset
88
96
@@ -448,7 +456,7 @@ object Parsers {
448
456
val topInfo = opStack.head
449
457
opStack = opStack.tail
450
458
val od = reduceStack(base, topInfo.operand, 0 , true )
451
- return atPos(od.pos.start , topInfo.offset) {
459
+ return atPos(startPos(od) , topInfo.offset) {
452
460
PostfixOp (od, topInfo.operator)
453
461
}
454
462
}
@@ -492,7 +500,7 @@ object Parsers {
492
500
493
501
/** Accept identifier acting as a selector on given tree `t`. */
494
502
def selector (t : Tree ): Tree =
495
- atPos(t.pos.start , in.offset) { Select (t, ident()) }
503
+ atPos(startPos(t) , in.offset) { Select (t, ident()) }
496
504
497
505
/** Selectors ::= ident { `.' ident()
498
506
*
@@ -728,7 +736,7 @@ object Parsers {
728
736
729
737
def refinedTypeRest (t : Tree ): Tree = {
730
738
newLineOptWhenFollowedBy(LBRACE )
731
- if (in.token == LBRACE ) refinedTypeRest(atPos(t.pos.start ) { RefinedTypeTree (t, refinement()) })
739
+ if (in.token == LBRACE ) refinedTypeRest(atPos(startPos(t) ) { RefinedTypeTree (t, refinement()) })
732
740
else t
733
741
}
734
742
@@ -749,7 +757,7 @@ object Parsers {
749
757
def annotType (): Tree = annotTypeRest(simpleType())
750
758
751
759
def annotTypeRest (t : Tree ): Tree =
752
- if (in.token == AT ) annotTypeRest(atPos(t.pos.start ) { Annotated (t, annot()) })
760
+ if (in.token == AT ) annotTypeRest(atPos(startPos(t) ) { Annotated (t, annot()) })
753
761
else t
754
762
755
763
/** SimpleType ::= SimpleType TypeArgs
@@ -780,19 +788,19 @@ object Parsers {
780
788
val handleSingletonType : Tree => Tree = t =>
781
789
if (in.token == TYPE ) {
782
790
in.nextToken()
783
- atPos(t.pos.start ) { SingletonTypeTree (t) }
791
+ atPos(startPos(t) ) { SingletonTypeTree (t) }
784
792
} else t
785
793
786
794
private def simpleTypeRest (t : Tree ): Tree = in.token match {
787
795
case HASH => simpleTypeRest(typeProjection(t))
788
- case LBRACKET => simpleTypeRest(atPos(t.pos.start ) { AppliedTypeTree (t, typeArgs(namedOK = true )) })
796
+ case LBRACKET => simpleTypeRest(atPos(startPos(t) ) { AppliedTypeTree (t, typeArgs(namedOK = true )) })
789
797
case _ => t
790
798
}
791
799
792
800
private def typeProjection (t : Tree ): Tree = {
793
801
accept(HASH )
794
802
val id = typeIdent()
795
- atPos(t.pos.start, id.pos.start ) { Select (t, id.name) }
803
+ atPos(startPos(t), startPos(id) ) { Select (t, id.name) }
796
804
}
797
805
798
806
/** NamedTypeArg ::= id `=' Type
@@ -846,7 +854,7 @@ object Parsers {
846
854
val t = toplevelTyp()
847
855
if (isIdent(nme.raw.STAR )) {
848
856
in.nextToken()
849
- atPos(t.pos.start ) { PostfixOp (t, nme.raw.STAR ) }
857
+ atPos(startPos(t) ) { PostfixOp (t, nme.raw.STAR ) }
850
858
} else t
851
859
}
852
860
@@ -971,7 +979,7 @@ object Parsers {
971
979
val t = expr1(location)
972
980
if (in.token == ARROW ) {
973
981
placeholderParams = saved
974
- closureRest(t.pos.start , location, convertToParams(t))
982
+ closureRest(startPos(t) , location, convertToParams(t))
975
983
}
976
984
else if (isWildcard(t)) {
977
985
placeholderParams = placeholderParams ::: saved
@@ -1025,7 +1033,7 @@ object Parsers {
1025
1033
assert(handlerStart != - 1 )
1026
1034
syntaxError(
1027
1035
new EmptyCatchBlock (body),
1028
- Position (handlerStart, handler.pos.end )
1036
+ Position (handlerStart, endPos( handler) )
1029
1037
)
1030
1038
case _ =>
1031
1039
}
@@ -1035,7 +1043,7 @@ object Parsers {
1035
1043
else {
1036
1044
if (handler.isEmpty) warning(
1037
1045
EmptyCatchAndFinallyBlock (body),
1038
- source atPos Position (tryOffset, body.pos.end )
1046
+ source atPos Position (tryOffset, endPos( body) )
1039
1047
)
1040
1048
EmptyTree
1041
1049
}
@@ -1057,21 +1065,21 @@ object Parsers {
1057
1065
case EQUALS =>
1058
1066
t match {
1059
1067
case Ident (_) | Select (_, _) | Apply (_, _) =>
1060
- atPos(t.pos.start , in.skipToken()) { Assign (t, expr()) }
1068
+ atPos(startPos(t) , in.skipToken()) { Assign (t, expr()) }
1061
1069
case _ =>
1062
1070
t
1063
1071
}
1064
1072
case COLON =>
1065
1073
ascription(t, location)
1066
1074
case MATCH =>
1067
- atPos(t.pos.start , in.skipToken()) {
1075
+ atPos(startPos(t) , in.skipToken()) {
1068
1076
inBraces(Match (t, caseClauses()))
1069
1077
}
1070
1078
case _ =>
1071
1079
t
1072
1080
}
1073
1081
1074
- def ascription (t : Tree , location : Location .Value ) = atPos(t.pos.start , in.skipToken()) {
1082
+ def ascription (t : Tree , location : Location .Value ) = atPos(startPos(t) , in.skipToken()) {
1075
1083
in.token match {
1076
1084
case USCORE =>
1077
1085
val uscoreStart = in.skipToken()
@@ -1105,7 +1113,7 @@ object Parsers {
1105
1113
val id = termIdent()
1106
1114
val paramExpr =
1107
1115
if (location == Location .InBlock && in.token == COLON )
1108
- atPos(id.pos.start , in.skipToken()) { Typed (id, infixType()) }
1116
+ atPos(startPos(id) , in.skipToken()) { Typed (id, infixType()) }
1109
1117
else
1110
1118
id
1111
1119
closureRest(start, location, convertToParam(paramExpr, mods) :: Nil )
@@ -1194,13 +1202,13 @@ object Parsers {
1194
1202
in.nextToken()
1195
1203
simpleExprRest(selector(t), canApply = true )
1196
1204
case LBRACKET =>
1197
- val tapp = atPos(t.pos.start , in.offset) { TypeApply (t, typeArgs(namedOK = true )) }
1205
+ val tapp = atPos(startPos(t) , in.offset) { TypeApply (t, typeArgs(namedOK = true )) }
1198
1206
simpleExprRest(tapp, canApply = true )
1199
1207
case LPAREN | LBRACE if canApply =>
1200
- val app = atPos(t.pos.start , in.offset) { Apply (t, argumentExprs()) }
1208
+ val app = atPos(startPos(t) , in.offset) { Apply (t, argumentExprs()) }
1201
1209
simpleExprRest(app, canApply = true )
1202
1210
case USCORE =>
1203
- atPos(t.pos.start , in.skipToken()) { PostfixOp (t, nme.WILDCARD ) }
1211
+ atPos(startPos(t) , in.skipToken()) { PostfixOp (t, nme.WILDCARD ) }
1204
1212
case _ =>
1205
1213
t
1206
1214
}
@@ -1284,7 +1292,7 @@ object Parsers {
1284
1292
if (in.token == IF ) guard()
1285
1293
else {
1286
1294
val pat = pattern1()
1287
- if (in.token == EQUALS ) atPos(pat.pos.start , in.skipToken()) { GenAlias (pat, expr()) }
1295
+ if (in.token == EQUALS ) atPos(startPos( pat) , in.skipToken()) { GenAlias (pat, expr()) }
1288
1296
else generatorRest(pat)
1289
1297
}
1290
1298
@@ -1293,7 +1301,7 @@ object Parsers {
1293
1301
def generator (): Tree = generatorRest(pattern1())
1294
1302
1295
1303
def generatorRest (pat : Tree ) =
1296
- atPos(pat.pos.start , accept(LARROW )) { GenFrom (pat, expr()) }
1304
+ atPos(startPos( pat) , accept(LARROW )) { GenFrom (pat, expr()) }
1297
1305
1298
1306
/** ForExpr ::= `for' (`(' Enumerators `)' | `{' Enumerators `}')
1299
1307
* {nl} [`yield'] Expr
@@ -1357,7 +1365,7 @@ object Parsers {
1357
1365
val pattern = () => {
1358
1366
val pat = pattern1()
1359
1367
if (isIdent(nme.raw.BAR ))
1360
- atPos(pat.pos.start ) { Alternative (pat :: patternAlts()) }
1368
+ atPos(startPos( pat) ) { Alternative (pat :: patternAlts()) }
1361
1369
else pat
1362
1370
}
1363
1371
@@ -1383,15 +1391,15 @@ object Parsers {
1383
1391
// compatibility for Scala2 `x @ _*` syntax
1384
1392
infixPattern() match {
1385
1393
case pt @ Ident (tpnme.WILDCARD_STAR ) =>
1386
- migrationWarningOrError(" The syntax `x @ _*' is no longer supported; use `x : _*' instead" , p.pos.start )
1387
- atPos(p.pos.start , offset) { Typed (p, pt) }
1394
+ migrationWarningOrError(" The syntax `x @ _*' is no longer supported; use `x : _*' instead" , startPos(p) )
1395
+ atPos(startPos(p) , offset) { Typed (p, pt) }
1388
1396
case p =>
1389
- atPos(p.pos.start , offset) { Bind (name, p) }
1397
+ atPos(startPos(p) , offset) { Bind (name, p) }
1390
1398
}
1391
1399
case p @ Ident (tpnme.WILDCARD_STAR ) =>
1392
1400
// compatibility for Scala2 `_*` syntax
1393
- migrationWarningOrError(" The syntax `_*' is no longer supported; use `x : _*' instead" , p.pos.start )
1394
- atPos(p.pos.start ) { Typed (Ident (nme.WILDCARD ), p) }
1401
+ migrationWarningOrError(" The syntax `_*' is no longer supported; use `x : _*' instead" , startPos(p) )
1402
+ atPos(startPos(p) ) { Typed (Ident (nme.WILDCARD ), p) }
1395
1403
case p =>
1396
1404
p
1397
1405
}
@@ -1415,7 +1423,7 @@ object Parsers {
1415
1423
val simplePattern = () => in.token match {
1416
1424
case IDENTIFIER | BACKQUOTED_IDENT | THIS =>
1417
1425
path(thisOK = true ) match {
1418
- case id @ Ident (nme.raw.MINUS ) if isNumericLit => literal(id.pos.start )
1426
+ case id @ Ident (nme.raw.MINUS ) if isNumericLit => literal(startPos(id) )
1419
1427
case t => simplePatternRest(t)
1420
1428
}
1421
1429
case USCORE =>
@@ -1445,9 +1453,9 @@ object Parsers {
1445
1453
def simplePatternRest (t : Tree ): Tree = {
1446
1454
var p = t
1447
1455
if (in.token == LBRACKET )
1448
- p = atPos(t.pos.start , in.offset) { TypeApply (p, typeArgs()) }
1456
+ p = atPos(startPos(t) , in.offset) { TypeApply (p, typeArgs()) }
1449
1457
if (in.token == LPAREN )
1450
- p = atPos(t.pos.start , in.offset) { Apply (p, argumentPatterns()) }
1458
+ p = atPos(startPos(t) , in.offset) { Apply (p, argumentPatterns()) }
1451
1459
p
1452
1460
}
1453
1461
@@ -1573,7 +1581,8 @@ object Parsers {
1573
1581
case Select (qual, name) => cpy.Select (tree)(adjustStart(start)(qual), name)
1574
1582
case _ => tree
1575
1583
}
1576
- if (start < tree1.pos.start) tree1.withPos(tree1.pos.withStart(start))
1584
+ if (tree1.pos.exists && start < tree1.pos.start)
1585
+ tree1.withPos(tree1.pos.withStart(start))
1577
1586
else tree1
1578
1587
}
1579
1588
@@ -1804,7 +1813,7 @@ object Parsers {
1804
1813
def importSelector (): Tree = {
1805
1814
val from = termIdentOrWildcard()
1806
1815
if (from.name != nme.WILDCARD && in.token == ARROW )
1807
- atPos(from.pos.start , in.skipToken()) {
1816
+ atPos(startPos( from) , in.skipToken()) {
1808
1817
Thicket (from, termIdentOrWildcard())
1809
1818
}
1810
1819
else from
0 commit comments