Skip to content

Fix #8982: Insert colons when rewriting classes to indentation syntax #9002

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 16 additions & 15 deletions compiler/src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ object Parsers {
def inBraces[T](body: => T): T = enclosed(LBRACE, body)
def inBrackets[T](body: => T): T = enclosed(LBRACKET, body)

def inBracesOrIndented[T](body: => T): T =
def inBracesOrIndented[T](body: => T, rewriteWithColon: Boolean = false): T =
if (in.token == INDENT) {
val rewriteToBraces =
in.rewriteNoIndent &&
Expand All @@ -582,12 +582,12 @@ object Parsers {
else enclosed(INDENT, body)
}
else
if (in.rewriteToIndent) bracesToIndented(body)
if (in.rewriteToIndent) bracesToIndented(body, rewriteWithColon)
else inBraces(body)

def inDefScopeBraces[T](body: => T): T = {
def inDefScopeBraces[T](body: => T, rewriteWithColon: Boolean = false): T = {
val saved = lastStatOffset
try inBracesOrIndented(body)
try inBracesOrIndented(body, rewriteWithColon)
finally lastStatOffset = saved
}

Expand Down Expand Up @@ -775,8 +775,9 @@ object Parsers {
* rewriting back to braces does not work after `=>` (since in most cases braces are omitted
* after a `=>` it would be annoying if braces were inserted).
*/
def bracesToIndented[T](body: => T): T = {
val colonRequired = possibleColonOffset == in.lastOffset
def bracesToIndented[T](body: => T, rewriteWithColon: Boolean): T = {
val underColonSyntax = possibleColonOffset == in.lastOffset
val colonRequired = rewriteWithColon || underColonSyntax
val (startOpening, endOpening) = startingElimRegion(colonRequired)
val isOutermost = in.currentRegion.isOutermost
def allBraces(r: Region): Boolean = r match {
Expand All @@ -795,10 +796,10 @@ object Parsers {
}
})
canRewrite &= (in.isAfterLineEnd || statCtdTokens.contains(in.token)) // test (5)
if (canRewrite && (!colonRequired || in.colonSyntax)) {
if (canRewrite && (!underColonSyntax || in.colonSyntax)) {
val openingPatchStr =
if (!colonRequired) ""
else if (testChar(startOpening - 1, Chars.isOperatorPart(_))) " :"
if !colonRequired then ""
else if testChar(startOpening - 1, Chars.isOperatorPart(_)) then " :"
else ":"
val (startClosing, endClosing) = closingElimRegion()
patch(source, Span(startOpening, endOpening), openingPatchStr)
Expand Down Expand Up @@ -1736,7 +1737,8 @@ object Parsers {

/** Refinement ::= `{' RefineStatSeq `}'
*/
def refinement(): List[Tree] = inBracesOrIndented(refineStatSeq())
def refinement(): List[Tree] =
inBracesOrIndented(refineStatSeq(), rewriteWithColon = true)

/** TypeBounds ::= [`>:' Type] [`<:' Type]
*/
Expand Down Expand Up @@ -2469,11 +2471,10 @@ object Parsers {
val pos = t.sourcePos
pos.startLine < pos.endLine
}
if (rewriteToNewSyntax(Span(start)) && (leading == LBRACE || !hasMultiLineEnum)) {
if in.newSyntax && in.rewrite && (leading == LBRACE || !hasMultiLineEnum) then
// Don't rewrite if that could change meaning of newlines
newLinesOpt()
dropParensOrBraces(start, if (in.token == YIELD || in.token == DO) "" else "do")
}
}
in.observeIndented()
res
Expand Down Expand Up @@ -3687,7 +3688,7 @@ object Parsers {
Template(constr, parents, derived, self, stats)

def templateBody(): (ValDef, List[Tree]) =
val r = inDefScopeBraces { templateStatSeq() }
val r = inDefScopeBraces(templateStatSeq(), rewriteWithColon = true)
if in.token == WITH then
syntaxError(EarlyDefinitionsNotSupported())
in.nextToken()
Expand All @@ -3706,7 +3707,7 @@ object Parsers {
def packaging(start: Int): Tree =
val pkg = qualId()
possibleTemplateStart()
val stats = inDefScopeBraces(topStatSeq())
val stats = inDefScopeBraces(topStatSeq(), rewriteWithColon = true)
makePackaging(start, pkg, stats)

/** TopStatSeq ::= TopStat {semi TopStat}
Expand Down Expand Up @@ -3898,7 +3899,7 @@ object Parsers {
if in.token == EOF then
ts += makePackaging(start, pkg, List())
else if in.isNestedStart then
ts += inDefScopeBraces(makePackaging(start, pkg, topStatSeq()))
ts += inDefScopeBraces(makePackaging(start, pkg, topStatSeq()), rewriteWithColon = true)
continue = true
else
acceptStatSep()
Expand Down
14 changes: 14 additions & 0 deletions tests/pos/i8982.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

object Foo {
def bar(x: Int): Unit = {
println(x)
}
}

class Baz(n: Int) {
def printRepeat(repeat: Int) = {
for {
x <- 1 to repeat
} println(s"$x - ${n * x}")
}
}
1 change: 1 addition & 0 deletions tests/run/rainwater.check
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rainWater captured by List(0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1) = 6
21 changes: 21 additions & 0 deletions tests/run/rainwater.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

def rainWater(vec: List[Int]): Int =
if vec.isEmpty then 0
else
val mx = vec.max
val split = vec.indexWhere(_ == mx)
rainWater1(0, vec.take(split + 1))
+ rainWater1(0, vec.drop(split).reverse)

def rainWater1(mx: Int, xs: List[Int]): Int = xs match
case x :: rest =>
val newMx = x max mx
newMx - x + rainWater1(newMx, rest)
case _ =>
0

def test(xs: Int*) =
println(s"rainWater captured by ${xs.toList} = ${rainWater(xs.toList)}")

@main def Test =
test(0,1,0,2,1,0,1,3,2,1,2,1)