Skip to content

Commit

Permalink
Backport Refine condition of leading infix operator
Browse files Browse the repository at this point in the history
  • Loading branch information
som-snytt committed Apr 11, 2021
1 parent 86bca17 commit 1f8dc38
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 5 deletions.
23 changes: 18 additions & 5 deletions src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
Expand Up @@ -432,18 +432,31 @@ trait Scanners extends ScannersCommon {
token = nl
}

/* A leading infix operator must be followed by a lexically suitable expression.
* Usually any simple expr will do. However, if the op is backtick style, make
* sure it is not followed by a binary op, which suggests the backticked identifier
* is a reference.
*/
def followedByInfixRHS: Boolean = {
val current = token
def isOp: Boolean = token == IDENTIFIER && isOperatorPart(name.charAt(name.length - 1))
def isCandidateInfixRHS: Boolean =
isSimpleExprIntroToken(token) &&
(current != BACKQUOTED_IDENT || !isOp || nme.raw.isUnary(name))
lookingAhead {
isCandidateInfixRHS ||
token == NEWLINE && { nextToken() ; isCandidateInfixRHS }
}
}

/* A leading symbolic or backquoted identifier is treated as an infix operator
* if it is followed by at least one ' ' and a token on the same line
* that can start an expression.
*/
def isLeadingInfixOperator =
allowLeadingInfixOperators &&
(token == BACKQUOTED_IDENT || token == IDENTIFIER && isOperatorPart(name.charAt(name.length - 1))) &&
ch <= ' ' && lookingAhead {
// force a NEWLINE after current token if it is on its own line
isSimpleExprIntroToken(token) ||
token == NEWLINE && { nextToken() ; isSimpleExprIntroToken(token) }
}
ch <= ' ' && followedByInfixRHS

/* Insert NEWLINE or NEWLINES if
* - we are after a newline
Expand Down
6 changes: 6 additions & 0 deletions test/files/neg/t12071.scala
Expand Up @@ -33,4 +33,10 @@ object C {
def `test-1`: Int = 23
def `test-2`: Int = 42
def compareTo(x: Int) = println("lol")

var `test-3`: List[Int] = Nil

// since ++ is not unary, test-3 is not taken as an operator; this test doesn't fix y above.
def yy = List.empty[Int] ++
`test-3` ++ `test-3`
}
21 changes: 21 additions & 0 deletions test/files/pos/i11371.scala
@@ -0,0 +1,21 @@
// scalac: -Xsource:3
//
object HelloWorld {
def whileLoop: Int = {
var i = 0
var acc = 0
while (i < 3) {
var `i'` = 0
while (`i'` < 4) {
acc += (i * `i'`)
`i'` += 1
}
i += 1
}
acc
}

def main(args: Array[String]): Unit = {
println(s"hello world: ${whileLoop}")
}
}

0 comments on commit 1f8dc38

Please sign in to comment.