Skip to content

Commit 5951f69

Browse files
committed
Simplify treatment of single-token lookahead in Scanner
No need to start a separate scanner; we can simply use the existing prev/next logic.
1 parent a7ef3e2 commit 5951f69

File tree

2 files changed

+34
-32
lines changed

2 files changed

+34
-32
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,9 @@ object Parsers {
206206
def isBindingIntro: Boolean = {
207207
in.token match {
208208
case USCORE => true
209-
case IDENTIFIER | BACKQUOTED_IDENT => in.lookaheadIn(BitSet(ARROW, CTXARROW))
209+
case IDENTIFIER | BACKQUOTED_IDENT =>
210+
val nxt = in.lookahead.token
211+
nxt == ARROW || nxt == CTXARROW
210212
case LPAREN =>
211213
val lookahead = in.LookaheadScanner()
212214
lookahead.skipParens()
@@ -235,7 +237,7 @@ object Parsers {
235237
*/
236238
def isSplice: Boolean =
237239
in.token == IDENTIFIER && in.name(0) == '$' && {
238-
if (in.name.length == 1) in.lookaheadIn(BitSet(LBRACE))
240+
if in.name.length == 1 then in.lookahead.token == LBRACE
239241
else (staged & StageKind.Quoted) != 0
240242
}
241243

@@ -1506,7 +1508,10 @@ object Parsers {
15061508

15071509
/** Is current ident a `*`, and is it followed by a `)` or `,`? */
15081510
def isPostfixStar: Boolean =
1509-
in.name == nme.raw.STAR && in.lookaheadIn(BitSet(RPAREN, COMMA))
1511+
in.name == nme.raw.STAR && {
1512+
val nxt = in.lookahead.token
1513+
nxt == RPAREN || nxt == COMMA
1514+
}
15101515

15111516
def infixTypeRest(t: Tree): Tree =
15121517
infixOps(t, canStartTypeTokens, refinedType, isType = true, isOperator = !isPostfixStar)
@@ -1588,11 +1593,10 @@ object Parsers {
15881593
else if (in.token == LBRACE)
15891594
atSpan(in.offset) { RefinedTypeTree(EmptyTree, refinement()) }
15901595
else if (isSimpleLiteral) { SingletonTypeTree(literal(inType = true)) }
1591-
else if (isIdent(nme.raw.MINUS) && in.lookaheadIn(numericLitTokens)) {
1596+
else if isIdent(nme.raw.MINUS) && numericLitTokens.contains(in.lookahead.token) then
15921597
val start = in.offset
15931598
in.nextToken()
15941599
SingletonTypeTree(literal(negOffset = start, inType = true))
1595-
}
15961600
else if (in.token == USCORE) {
15971601
if sourceVersion.isAtLeast(`3.1`) then
15981602
deprecationWarning(em"`_` is deprecated for wildcard arguments of types: use `?` instead")
@@ -2012,7 +2016,7 @@ object Parsers {
20122016
case _ =>
20132017
if isIdent(nme.inline)
20142018
&& !in.inModifierPosition()
2015-
&& in.lookaheadIn(in.canStartExprTokens)
2019+
&& in.canStartExprTokens.contains(in.lookahead.token)
20162020
then
20172021
val start = in.skipToken()
20182022
in.token match
@@ -3005,7 +3009,7 @@ object Parsers {
30053009
val isParams =
30063010
!impliedMods.is(Given)
30073011
|| startParamTokens.contains(in.token)
3008-
|| isIdent && (in.name == nme.inline || in.lookaheadIn(BitSet(COLON)))
3012+
|| isIdent && (in.name == nme.inline || in.lookahead.token == COLON)
30093013
if isParams then commaSeparated(() => param())
30103014
else contextTypes(ofClass, nparams)
30113015
checkVarArgsRules(clause)
@@ -3567,7 +3571,7 @@ object Parsers {
35673571
val tparams = typeParamClauseOpt(ParamOwner.Def)
35683572
newLineOpt()
35693573
val vparamss =
3570-
if in.token == LPAREN && in.lookaheadIn(nme.using)
3574+
if in.token == LPAREN && in.lookahead.isIdent(nme.using)
35713575
then paramClauses(givenOnly = true)
35723576
else Nil
35733577
newLinesOpt()

compiler/src/dotty/tools/dotc/parsing/Scanners.scala

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,13 @@ object Scanners {
9898
this.strVal = td.strVal
9999
this.base = td.base
100100
}
101+
102+
def isNewLine = token == NEWLINE || token == NEWLINES
103+
def isIdent = token == IDENTIFIER || token == BACKQUOTED_IDENT
104+
def isIdent(name: Name) = token == IDENTIFIER && this.name == name
105+
106+
def isNestedStart = token == LBRACE || token == INDENT
107+
def isNestedEnd = token == RBRACE || token == OUTDENT
101108
}
102109

103110
abstract class ScannerCommon(source: SourceFile)(implicit ctx: Context) extends CharArrayReader with TokenData {
@@ -535,7 +542,7 @@ object Scanners {
535542

536543
def observeColonEOL(): Unit =
537544
if token == COLON then
538-
lookahead()
545+
lookAhead()
539546
val atEOL = isAfterLineEnd || token == EOF
540547
reset()
541548
if atEOL then token = COLONEOL
@@ -562,7 +569,7 @@ object Scanners {
562569
insert(OUTDENT, offset)
563570
case _ =>
564571

565-
def lookahead() = {
572+
def lookAhead() = {
566573
prev.copyFrom(this)
567574
lastOffset = lastCharOffset
568575
fetchToken()
@@ -591,12 +598,12 @@ object Scanners {
591598
}
592599
token match {
593600
case CASE =>
594-
lookahead()
601+
lookAhead()
595602
if (token == CLASS) fuse(CASECLASS)
596603
else if (token == OBJECT) fuse(CASEOBJECT)
597604
else reset()
598605
case SEMI =>
599-
lookahead()
606+
lookAhead()
600607
if (token != ELSE) reset()
601608
case COMMA =>
602609
def isEnclosedInParens(r: Region): Boolean = r match
@@ -608,7 +615,7 @@ object Scanners {
608615
insert(OUTDENT, offset)
609616
currentRegion = r.outer
610617
case _ =>
611-
lookahead()
618+
lookAhead()
612619
if isAfterLineEnd
613620
&& (token == RPAREN || token == RBRACKET || token == RBRACE || token == OUTDENT)
614621
then
@@ -892,6 +899,15 @@ object Scanners {
892899

893900
// Lookahead ---------------------------------------------------------------
894901

902+
/** The next token after this one.
903+
* Newlines and indent/unindent tokens are skipped.
904+
*/
905+
def lookahead: TokenData =
906+
if next.token == EMPTY then
907+
lookAhead()
908+
reset()
909+
next
910+
895911
class LookaheadScanner() extends Scanner(source, offset)
896912

897913
/** Skip matching pairs of `(...)` or `[...]` parentheses.
@@ -904,17 +920,6 @@ object Scanners {
904920
if token == opening && multiple then skipParens() else nextToken()
905921
nextToken()
906922

907-
/** Is the token following the current one in `tokens`? */
908-
def lookaheadIn(follow: BitSet | TermName): Boolean =
909-
val lookahead = LookaheadScanner()
910-
while
911-
lookahead.nextToken()
912-
lookahead.isNewLine
913-
do ()
914-
follow match
915-
case tokens: BitSet => tokens.contains(lookahead.token)
916-
case name: TermName => lookahead.token == IDENTIFIER && lookahead.name == name
917-
918923
/** Is the current token in a position where a modifier is allowed? */
919924
def inModifierPosition(): Boolean = {
920925
val lookahead = LookaheadScanner()
@@ -1010,14 +1015,7 @@ object Scanners {
10101015
isSoftModifier && inModifierPosition()
10111016

10121017
def isSoftModifierInParamModifierPosition: Boolean =
1013-
isSoftModifier && !lookaheadIn(BitSet(COLON))
1014-
1015-
def isNewLine = token == NEWLINE || token == NEWLINES
1016-
def isIdent = token == IDENTIFIER || token == BACKQUOTED_IDENT
1017-
def isIdent(name: Name) = token == IDENTIFIER && this.name == name
1018-
1019-
def isNestedStart = token == LBRACE || token == INDENT
1020-
def isNestedEnd = token == RBRACE || token == OUTDENT
1018+
isSoftModifier && lookahead.token != COLON
10211019

10221020
def canStartStatTokens =
10231021
if migrateTo3 then canStartStatTokens2 else canStartStatTokens3

0 commit comments

Comments
 (0)