Skip to content

Commit 0af5efb

Browse files
committed
Refine condition of leading infix operator
1 parent 5b46900 commit 0af5efb

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

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

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ object Scanners {
7777

7878
/** Is current token first one after a newline? */
7979
def isAfterLineEnd: Boolean = lineOffset >= 0
80+
81+
def isOperator =
82+
token == IDENTIFIER && isOperatorPart(name(name.length - 1))
8083
}
8184

8285
abstract class ScannerCommon(source: SourceFile)(using Context) extends CharArrayReader with TokenData {
@@ -348,12 +351,27 @@ object Scanners {
348351
&& (isWhitespace(ch) || ch == LF)
349352
&& !pastBlankLine
350353
&& {
354+
// Is current lexeme assumed to start an expression?
355+
// This is the case if the lexime is one of the tokens that
356+
// starts an expression. Furthermore, if the previous token is
357+
// in backticks, the lexeme may not be a binary operator.
358+
// I.e. in
359+
//
360+
// a
361+
// `x` += 1
362+
//
363+
// `+=` is not assumed to start an expression since it follows an identifier
364+
// in backticks and is a binary operator. Hence, `x` is not classified as a
365+
// leading infix operator.
366+
def assumeStartsExpr(lexeme: TokenData) =
367+
canStartExprTokens.contains(lexeme.token)
368+
&& (token != BACKQUOTED_IDENT || !lexeme.isOperator || nme.raw.isUnary(lexeme.name))
351369
val lookahead = LookaheadScanner()
352370
lookahead.allowLeadingInfixOperators = false
353371
// force a NEWLINE a after current token if it is on its own line
354372
lookahead.nextToken()
355-
canStartExprTokens.contains(lookahead.token)
356-
|| lookahead.token == NEWLINE && canStartExprTokens.contains(lookahead.next.token)
373+
assumeStartsExpr(lookahead)
374+
|| lookahead.token == NEWLINE && assumeStartsExpr(lookahead.next)
357375
}
358376
&& {
359377
if migrateTo3 then

tests/pos/i11371.scala

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
object HelloWorld {
2+
def whileLoop: Int = {
3+
var i = 0
4+
var acc = 0
5+
while (i < 3) {
6+
var `i'` = 0
7+
while (`i'` < 4) {
8+
acc += (i * `i'`)
9+
`i'` += 1
10+
}
11+
i += 1
12+
}
13+
acc
14+
}
15+
16+
def main(args: Array[String]): Unit = {
17+
println(s"hello world: ${whileLoop}")
18+
}
19+
}

tests/run/i7031.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
val a = 5
33
val x = 1
44

5-
+ //
6-
`a` * 6
5+
+ `a` * 6
76

87
assert(x == 1, x)
98
}

0 commit comments

Comments
 (0)