Skip to content

Commit a0c370a

Browse files
authored
Merge pull request #6994 from dotty-staging/drop-do-while
Drop do while
2 parents e22ed0b + 46d2324 commit a0c370a

File tree

41 files changed

+145
-120
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+145
-120
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: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -301,9 +301,6 @@ object Parsers {
301301
def deprecationWarning(msg: => Message, offset: Int = in.offset): Unit =
302302
ctx.deprecationWarning(msg, source.atSpan(Span(offset)))
303303

304-
def errorOrMigrationWarning(msg: => Message, offset: Int = in.offset): Unit =
305-
ctx.errorOrMigrationWarning(msg, source.atSpan(Span(offset)))
306-
307304
/** Issue an error at current offset that input is incomplete */
308305
def incompleteInputError(msg: => Message): Unit =
309306
ctx.incompleteInputError(msg, source.atSpan(Span(in.offset)))
@@ -392,12 +389,6 @@ object Parsers {
392389
finally staged = saved
393390
}
394391

395-
def migrationWarningOrError(msg: String, offset: Int = in.offset): Unit =
396-
if (in.isScala2Mode)
397-
ctx.migrationWarning(msg, source.atSpan(Span(offset)))
398-
else
399-
syntaxError(msg, offset)
400-
401392
/* ---------- TREE CONSTRUCTION ------------------------------------------- */
402393

403394
/** Convert tree to formal parameter list
@@ -780,9 +771,9 @@ object Parsers {
780771
Quote(t)
781772
}
782773
else {
783-
migrationWarningOrError(em"""symbol literal '${in.name} is no longer supported,
784-
|use a string literal "${in.name}" or an application Symbol("${in.name}") instead,
785-
|or enclose in braces '{${in.name}} if you want a quoted expression.""")
774+
in.errorOrMigrationWarning(em"""symbol literal '${in.name} is no longer supported,
775+
|use a string literal "${in.name}" or an application Symbol("${in.name}") instead,
776+
|or enclose in braces '{${in.name}} if you want a quoted expression.""")
786777
if (in.isScala2Mode) {
787778
patch(source, Span(in.offset, in.offset + 1), "Symbol(\"")
788779
patch(source, Span(in.charOffset - 1), "\")")
@@ -1216,7 +1207,7 @@ object Parsers {
12161207
AppliedTypeTree(toplevelTyp(), Ident(pname))
12171208
} :: contextBounds(pname)
12181209
case VIEWBOUND =>
1219-
errorOrMigrationWarning("view bounds `<%' are deprecated, use a context bound `:' instead")
1210+
in.errorOrMigrationWarning("view bounds `<%' are deprecated, use a context bound `:' instead")
12201211
atSpan(in.skipToken()) {
12211212
Function(Ident(pname) :: Nil, toplevelTyp())
12221213
} :: contextBounds(pname)
@@ -1339,12 +1330,30 @@ object Parsers {
13391330
WhileDo(cond, body)
13401331
}
13411332
case DO =>
1342-
atSpan(in.skipToken()) {
1333+
in.errorOrMigrationWarning(
1334+
i"""`do <body> while <cond>' is no longer supported,
1335+
|use `while {<body> ; <cond>} do ()' instead.
1336+
|The statement can be rewritten automatically under -language:Scala2 -migration -rewrite.
1337+
""")
1338+
val start = in.skipToken()
1339+
atSpan(start) {
13431340
val body = expr()
13441341
if (isStatSep) in.nextToken()
1342+
val whileStart = in.offset
13451343
accept(WHILE)
13461344
val cond = expr()
1347-
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(body :: Nil, cond), Literal(Constant(())))
13481357
}
13491358
case TRY =>
13501359
val tryOffset = in.offset
@@ -1525,7 +1534,7 @@ object Parsers {
15251534
if (ctx.settings.strict.value)
15261535
// Don't error in non-strict mode, as the alternative syntax "implicit (x: T) => ... "
15271536
// is not supported by Scala2.x
1528-
migrationWarningOrError(s"This syntax is no longer supported; parameter needs to be enclosed in (...)")
1537+
in.errorOrMigrationWarning(s"This syntax is no longer supported; parameter needs to be enclosed in (...)")
15291538
in.nextToken()
15301539
val t = infixType()
15311540
if (false && in.isScala2Mode) {
@@ -1933,15 +1942,15 @@ object Parsers {
19331942
infixPattern() match {
19341943
case pt @ Ident(tpnme.WILDCARD_STAR) =>
19351944
if (ctx.settings.strict.value)
1936-
migrationWarningOrError("The syntax `x @ _*' is no longer supported; use `x : _*' instead", startOffset(p))
1945+
in.errorOrMigrationWarning("The syntax `x @ _*' is no longer supported; use `x : _*' instead", Span(startOffset(p)))
19371946
atSpan(startOffset(p), offset) { Typed(p, pt) }
19381947
case pt =>
19391948
atSpan(startOffset(p), 0) { Bind(name, pt) }
19401949
}
19411950
case p @ Ident(tpnme.WILDCARD_STAR) =>
19421951
// compatibility for Scala2 `_*` syntax
19431952
if (ctx.settings.strict.value)
1944-
migrationWarningOrError("The syntax `_*' is no longer supported; use `x : _*' instead", startOffset(p))
1953+
in.errorOrMigrationWarning("The syntax `_*' is no longer supported; use `x : _*' instead", Span(startOffset(p)))
19451954
atSpan(startOffset(p)) { Typed(Ident(nme.WILDCARD), p) }
19461955
case p =>
19471956
p

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 ':'" )

0 commit comments

Comments
 (0)