Skip to content

Commit 2ff2b42

Browse files
committed
Drop do-while
Drop . Rewrite to instead. This can be done by the compiler under -rewrite.
1 parent d266232 commit 2ff2b42

File tree

30 files changed

+108
-83
lines changed

30 files changed

+108
-83
lines changed

compiler/src/dotty/tools/backend/jvm/BTypes.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -719,14 +719,15 @@ abstract class BTypes {
719719
var chainA = as
720720
var chainB = bs
721721
var fcs: ClassBType = null
722-
do {
722+
while {
723723
if (chainB contains chainA.head) fcs = chainA.head
724724
else if (chainA contains chainB.head) fcs = chainB.head
725725
else {
726726
chainA = chainA.tail
727727
chainB = chainB.tail
728728
}
729-
} while (fcs == null)
729+
fcs == null
730+
} do ()
730731
fcs
731732
}
732733

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,10 +1569,6 @@ object desugar {
15691569
case PrefixOp(op, t) =>
15701570
val nspace = if (ctx.mode.is(Mode.Type)) tpnme else nme
15711571
Select(t, nspace.UNARY_PREFIX ++ op.name)
1572-
case DoWhile(body, cond) =>
1573-
// while ({ { body }; { cond } }) { () }
1574-
// the inner blocks are there to protect the scopes of body and cond from each other
1575-
WhileDo(Block(Block(Nil, body), Block(Nil, cond)), Literal(Constant(())))
15761572
case ForDo(enums, body) =>
15771573
makeFor(nme.foreach, nme.foreach, enums, body) orElse tree
15781574
case ForYield(enums, body) =>

compiler/src/dotty/tools/dotc/ast/untpd.scala

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
102102
case class Quote(quoted: Tree)(implicit @constructorOnly src: SourceFile) extends TermTree
103103
case class Splice(expr: Tree)(implicit @constructorOnly src: SourceFile) extends TermTree
104104
case class TypSplice(expr: Tree)(implicit @constructorOnly src: SourceFile) extends TypTree
105-
case class DoWhile(body: Tree, cond: Tree)(implicit @constructorOnly src: SourceFile) extends TermTree
106105
case class ForYield(enums: List[Tree], expr: Tree)(implicit @constructorOnly src: SourceFile) extends TermTree
107106
case class ForDo(enums: List[Tree], body: Tree)(implicit @constructorOnly src: SourceFile) extends TermTree
108107
case class GenFrom(pat: Tree, expr: Tree, checkMode: GenCheckMode)(implicit @constructorOnly src: SourceFile) extends Tree
@@ -532,10 +531,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
532531
case tree: TypSplice if expr eq tree.expr => tree
533532
case _ => finalize(tree, untpd.TypSplice(expr)(tree.source))
534533
}
535-
def DoWhile(tree: Tree)(body: Tree, cond: Tree)(implicit ctx: Context): TermTree = tree match {
536-
case tree: DoWhile if (body eq tree.body) && (cond eq tree.cond) => tree
537-
case _ => finalize(tree, untpd.DoWhile(body, cond)(tree.source))
538-
}
539534
def ForYield(tree: Tree)(enums: List[Tree], expr: Tree)(implicit ctx: Context): TermTree = tree match {
540535
case tree: ForYield if (enums eq tree.enums) && (expr eq tree.expr) => tree
541536
case _ => finalize(tree, untpd.ForYield(enums, expr)(tree.source))
@@ -604,8 +599,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
604599
cpy.Splice(tree)(transform(expr))
605600
case TypSplice(expr) =>
606601
cpy.TypSplice(tree)(transform(expr))
607-
case DoWhile(body, cond) =>
608-
cpy.DoWhile(tree)(transform(body), transform(cond))
609602
case ForYield(enums, expr) =>
610603
cpy.ForYield(tree)(transform(enums), transform(expr))
611604
case ForDo(enums, body) =>
@@ -661,8 +654,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
661654
this(x, expr)
662655
case TypSplice(expr) =>
663656
this(x, expr)
664-
case DoWhile(body, cond) =>
665-
this(this(x, body), cond)
666657
case ForYield(enums, expr) =>
667658
this(this(x, enums), expr)
668659
case ForDo(enums, body) =>

compiler/src/dotty/tools/dotc/core/Denotations.scala

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -802,11 +802,11 @@ object Denotations {
802802
def history: List[SingleDenotation] = {
803803
val b = new ListBuffer[SingleDenotation]
804804
var current = initial
805-
do {
805+
while {
806806
b += (current)
807807
current = current.nextInRun
808-
}
809-
while (current ne initial)
808+
current ne initial
809+
} do ()
810810
b.toList
811811
}
812812

@@ -820,11 +820,12 @@ object Denotations {
820820
symbol.is(Permanent), // Permanent symbols are valid in all runIds
821821
s"denotation $this invalid in run ${ctx.runId}. ValidFor: $validFor")
822822
var d: SingleDenotation = this
823-
do {
823+
while {
824824
d.validFor = Period(ctx.period.runId, d.validFor.firstPhaseId, d.validFor.lastPhaseId)
825825
d.invalidateInheritedInfo()
826826
d = d.nextInRun
827-
} while (d ne this)
827+
d ne this
828+
} do ()
828829
this
829830
}
830831

@@ -1053,12 +1054,13 @@ object Denotations {
10531054
var cur = this
10541055
var cnt = 0
10551056
var interval = validFor
1056-
do {
1057+
while {
10571058
cur = cur.nextInRun
10581059
cnt += 1
10591060
assert(cnt <= MaxPossiblePhaseId, demandOutsideDefinedMsg)
10601061
interval |= cur.validFor
1061-
} while (cur ne this)
1062+
cur ne this
1063+
} do ()
10621064
interval
10631065
}
10641066

@@ -1075,12 +1077,13 @@ object Denotations {
10751077
var sb = new StringBuilder()
10761078
var cur = this
10771079
var cnt = 0
1078-
do {
1080+
while {
10791081
sb.append(" " + cur.validFor)
10801082
cur = cur.nextInRun
10811083
cnt += 1
10821084
if (cnt > MaxPossiblePhaseId) { sb.append(" ..."); cur = this }
1083-
} while (cur ne this)
1085+
cur ne this
1086+
} do ()
10841087
sb.toString
10851088
}
10861089

compiler/src/dotty/tools/dotc/core/Scopes.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,9 +382,9 @@ object Scopes {
382382
override final def lookupNextEntry(entry: ScopeEntry)(implicit ctx: Context): ScopeEntry = {
383383
var e = entry
384384
if (hashTable ne null)
385-
do { e = e.tail } while ((e ne null) && e.name != entry.name)
385+
while ({ e = e.tail ; (e ne null) && e.name != entry.name }) ()
386386
else
387-
do { e = e.prev } while ((e ne null) && e.name != entry.name)
387+
while ({ e = e.prev ; (e ne null) && e.name != entry.name }) ()
388388
e
389389
}
390390

compiler/src/dotty/tools/dotc/core/tasty/TastyBuffer.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,12 @@ class TastyBuffer(initialSize: Int) {
149149
var b = 0L
150150
var x = 0L
151151
var idx = at.index
152-
do {
152+
while {
153153
b = bytes(idx)
154154
x = (x << 7) | (b & 0x7f)
155155
idx += 1
156-
} while ((b & 0x80) == 0)
156+
(b & 0x80) == 0
157+
} do ()
157158
x
158159
}
159160

compiler/src/dotty/tools/dotc/core/tasty/TastyReader.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,12 @@ class TastyReader(val bytes: Array[Byte], start: Int, end: Int, val base: Int =
7575
def readLongNat(): Long = {
7676
var b = 0L
7777
var x = 0L
78-
do {
78+
while {
7979
b = bytes(bp)
8080
x = (x << 7) | (b & 0x7f)
8181
bp += 1
82-
} while ((b & 0x80) == 0)
82+
(b & 0x80) == 0
83+
} do ()
8384
x
8485
}
8586

compiler/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,10 +175,11 @@ class TreeBuffer extends TastyBuffer(50000) {
175175
//println(s"offsets: ${offsets.take(numOffsets).deep}")
176176
//println(s"deltas: ${delta.take(numOffsets).deep}")
177177
var saved = 0
178-
do {
178+
while {
179179
saved = adjustDeltas()
180180
pickling.println(s"adjusting deltas, saved = $saved")
181-
} while (saved > 0 && length / saved < 100)
181+
saved > 0 && length / saved < 100
182+
} do ()
182183
adjustOffsets()
183184
adjustTreeAddrs()
184185
val wasted = compress()

compiler/src/dotty/tools/dotc/core/unpickleScala2/PickleBuffer.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,11 @@ class PickleBuffer(data: Array[Byte], from: Int, to: Int) {
107107
def readLongNat(): Long = {
108108
var b = 0L
109109
var x = 0L
110-
do {
110+
while ({
111111
b = readByte()
112112
x = (x << 7) + (b & 0x7f)
113-
} while ((b & 0x80) != 0L)
113+
(b & 0x80) != 0L
114+
}) ()
114115
x
115116
}
116117

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,10 @@ abstract class CharArrayReader { self =>
9292
}
9393
}
9494
if (charOffset < buf.length && buf(charOffset) == 'u' && decodeUni && evenSlashPrefix) {
95-
do charOffset += 1
96-
while (charOffset < buf.length && buf(charOffset) == 'u')
95+
while {
96+
charOffset += 1
97+
charOffset < buf.length && buf(charOffset) == 'u'
98+
} do ()
9799
val code = udigit << 12 | udigit << 8 | udigit << 4 | udigit
98100
lastUnicodeOffset = charOffset
99101
ch = code.toChar

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ object JavaParsers {
141141
def skipAhead(): Unit = {
142142
var nparens = 0
143143
var nbraces = 0
144-
do {
144+
while ({
145145
in.token match {
146146
case LPAREN =>
147147
nparens += 1
@@ -157,7 +157,8 @@ object JavaParsers {
157157
nbraces -= 1
158158
case _ =>
159159
}
160-
} while (in.token != EOF && (nparens > 0 || nbraces > 0))
160+
in.token != EOF && (nparens > 0 || nbraces > 0)
161+
}) ()
161162
}
162163

163164
def skipTo(tokens: Int*): Unit = {

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

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,12 +1330,30 @@ object Parsers {
13301330
WhileDo(cond, body)
13311331
}
13321332
case DO =>
1333-
atSpan(in.skipToken()) {
1333+
in.errorOrMigrationWarning(
1334+
i"""`do <body> while <cond>' is no longer supported,
1335+
|use `while ({<body> ; <cond>}) ()' instead.
1336+
|The statement can be rewritten automatically under -language:Scala2 -migration -rewrite.
1337+
""")
1338+
val start = in.skipToken()
1339+
atSpan(start) {
13341340
val body = expr()
13351341
if (isStatSep) in.nextToken()
1342+
val whileStart = in.offset
13361343
accept(WHILE)
13371344
val cond = expr()
1338-
DoWhile(body, cond)
1345+
if (ctx.settings.migration.value) {
1346+
patch(source, Span(start, start + 2), "while ({")
1347+
patch(source, Span(whileStart, whileStart + 5), ";")
1348+
cond match {
1349+
case Parens(_) =>
1350+
patch(source, Span(cond.span.start, cond.span.start + 1), "")
1351+
patch(source, Span(cond.span.end - 1, cond.span.end), "")
1352+
case _ =>
1353+
}
1354+
patch(source, cond.span.endPos, "}) ()")
1355+
}
1356+
WhileDo(Block(Block(Nil, body), Block(Nil, cond)), Literal(Constant(())))
13391357
}
13401358
case TRY =>
13411359
val tryOffset = in.offset

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

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ object Scanners {
663663
skipComment()
664664
}
665665
else if (ch == '*') {
666-
do nextChar() while (ch == '*')
666+
while ({ nextChar() ; ch == '*' }) ()
667667
if (ch == '/') nextChar()
668668
else skipComment()
669669
}
@@ -703,17 +703,20 @@ object Scanners {
703703
/** Is the token following the current one in `tokens`? */
704704
def lookaheadIn(tokens: BitSet): Boolean = {
705705
val lookahead = lookaheadScanner
706-
do lookahead.nextToken()
707-
while (lookahead.token == NEWLINE || lookahead.token == NEWLINES)
706+
while ({
707+
lookahead.nextToken()
708+
lookahead.token == NEWLINE || lookahead.token == NEWLINES
709+
}) ()
708710
tokens.contains(lookahead.token)
709711
}
710712

711713
/** Is the current token in a position where a modifier is allowed? */
712714
def inModifierPosition(): Boolean = {
713715
val lookahead = lookaheadScanner
714-
do lookahead.nextToken()
715-
while (lookahead.token == NEWLINE || lookahead.token == NEWLINES ||
716-
lookahead.isSoftModifier)
716+
while ({
717+
lookahead.nextToken()
718+
lookahead.token == NEWLINE || lookahead.token == NEWLINES || lookahead.isSoftModifier
719+
}) ()
717720
modifierFollowers.contains(lookahead.token)
718721
}
719722

@@ -866,10 +869,11 @@ object Scanners {
866869
next.token = LBRACE
867870
} else if (Character.isUnicodeIdentifierStart(ch) || ch == '_') {
868871
finishStringPart()
869-
do {
872+
while ({
870873
putChar(ch)
871874
nextRawChar()
872-
} while (ch != SU && Character.isUnicodeIdentifierPart(ch))
875+
ch != SU && Character.isUnicodeIdentifierPart(ch)
876+
}) ()
873877
finishNamed(target = next)
874878
} else {
875879
error("invalid string interpolation: `$$', `$'ident or `$'BlockExpr expected")

compiler/src/dotty/tools/dotc/parsing/xml/MarkupParserCommon.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,7 @@ private[dotty] trait MarkupParserCommon {
110110

111111
val buf = new StringBuilder
112112

113-
do buf append ch_returning_nextch
114-
while (isNameChar(ch))
113+
while ({ buf append ch_returning_nextch ; isNameChar(ch) }) ()
115114

116115
if (buf.last == ':') {
117116
reportSyntaxError( "name cannot end in ':'" )

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -584,8 +584,6 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
584584
"(" ~ toTextGlobal(t) ~ ")"
585585
case Tuple(ts) =>
586586
"(" ~ toTextGlobal(ts, ", ") ~ ")"
587-
case DoWhile(cond, body) =>
588-
changePrec(GlobalPrec) { keywordStr("do ") ~ toText(body) ~ keywordStr(" while ") ~ toText(cond) }
589587
case ForYield(enums, expr) =>
590588
forText(enums, expr, keywordStr(" yield "))
591589
case ForDo(enums, expr) =>

compiler/src/dotty/tools/dotc/tastyreflect/ReflectionInternal.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend
455455
}
456456

457457
/** Normalizes non Blocks.
458-
* i) Put `while` and `doWhile` loops in their own blocks: `{ def while$() = ...; while$() }`
458+
* i) Put `while` loops in their own blocks: `{ def while$() = ...; while$() }`
459459
* ii) Put closures in their own blocks: `{ def anon$() = ...; closure(anon$, ...) }`
460460
*/
461461
private def normalizedLoops(tree: tpd.Tree) given Context: tpd.Tree = tree match {

compiler/src/dotty/tools/dotc/transform/LambdaLift.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,19 +252,20 @@ object LambdaLift {
252252

253253
/** Compute final free variables map `fvs by closing over caller dependencies. */
254254
private def computeFreeVars()(implicit ctx: Context): Unit =
255-
do {
255+
while ({
256256
changedFreeVars = false
257257
for {
258258
caller <- called.keys
259259
callee <- called(caller)
260260
fvs <- free get callee
261261
fv <- fvs
262262
} markFree(fv, caller)
263-
} while (changedFreeVars)
263+
changedFreeVars
264+
}) ()
264265

265266
/** Compute final liftedOwner map by closing over caller dependencies */
266267
private def computeLiftedOwners()(implicit ctx: Context): Unit =
267-
do {
268+
while ({
268269
changedLiftedOwner = false
269270
for {
270271
caller <- called.keys
@@ -282,7 +283,8 @@ object LambdaLift {
282283
narrowLiftedOwner(caller, calleeOwner)
283284
}
284285
}
285-
} while (changedLiftedOwner)
286+
changedLiftedOwner
287+
}) ()
286288

287289
private def newName(sym: Symbol)(implicit ctx: Context): Name =
288290
if (sym.isAnonymousFunction && sym.owner.is(Method))

compiler/src/dotty/tools/dotc/util/CommentParsing.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,10 @@ object CommentParsing {
172172
def skipVariable(str: String, start: Int): Int = {
173173
var idx = start
174174
if (idx < str.length && (str charAt idx) == '{') {
175-
do idx += 1
176-
while (idx < str.length && (str charAt idx) != '}')
175+
while {
176+
idx += 1
177+
idx < str.length && (str charAt idx) != '}'
178+
} do ()
177179
if (idx < str.length) idx + 1 else start
178180
} else {
179181
while (idx < str.length && isVarPart(str charAt idx))

0 commit comments

Comments
 (0)