Skip to content

Drop do while #6994

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 7 commits into from
Aug 6, 2019
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
5 changes: 3 additions & 2 deletions compiler/src/dotty/tools/backend/jvm/BTypes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -719,14 +719,15 @@ abstract class BTypes {
var chainA = as
var chainB = bs
var fcs: ClassBType = null
do {
while {
if (chainB contains chainA.head) fcs = chainA.head
else if (chainA contains chainB.head) fcs = chainB.head
else {
chainA = chainA.tail
chainB = chainB.tail
}
} while (fcs == null)
fcs == null
} do ()
fcs
}

Expand Down
4 changes: 0 additions & 4 deletions compiler/src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1569,10 +1569,6 @@ object desugar {
case PrefixOp(op, t) =>
val nspace = if (ctx.mode.is(Mode.Type)) tpnme else nme
Select(t, nspace.UNARY_PREFIX ++ op.name)
case DoWhile(body, cond) =>
// while ({ { body }; { cond } }) { () }
// the inner blocks are there to protect the scopes of body and cond from each other
WhileDo(Block(Block(Nil, body), Block(Nil, cond)), Literal(Constant(())))
case ForDo(enums, body) =>
makeFor(nme.foreach, nme.foreach, enums, body) orElse tree
case ForYield(enums, body) =>
Expand Down
9 changes: 0 additions & 9 deletions compiler/src/dotty/tools/dotc/ast/untpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
case class Quote(quoted: Tree)(implicit @constructorOnly src: SourceFile) extends TermTree
case class Splice(expr: Tree)(implicit @constructorOnly src: SourceFile) extends TermTree
case class TypSplice(expr: Tree)(implicit @constructorOnly src: SourceFile) extends TypTree
case class DoWhile(body: Tree, cond: Tree)(implicit @constructorOnly src: SourceFile) extends TermTree
case class ForYield(enums: List[Tree], expr: Tree)(implicit @constructorOnly src: SourceFile) extends TermTree
case class ForDo(enums: List[Tree], body: Tree)(implicit @constructorOnly src: SourceFile) extends TermTree
case class GenFrom(pat: Tree, expr: Tree, checkMode: GenCheckMode)(implicit @constructorOnly src: SourceFile) extends Tree
Expand Down Expand Up @@ -532,10 +531,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
case tree: TypSplice if expr eq tree.expr => tree
case _ => finalize(tree, untpd.TypSplice(expr)(tree.source))
}
def DoWhile(tree: Tree)(body: Tree, cond: Tree)(implicit ctx: Context): TermTree = tree match {
case tree: DoWhile if (body eq tree.body) && (cond eq tree.cond) => tree
case _ => finalize(tree, untpd.DoWhile(body, cond)(tree.source))
}
def ForYield(tree: Tree)(enums: List[Tree], expr: Tree)(implicit ctx: Context): TermTree = tree match {
case tree: ForYield if (enums eq tree.enums) && (expr eq tree.expr) => tree
case _ => finalize(tree, untpd.ForYield(enums, expr)(tree.source))
Expand Down Expand Up @@ -604,8 +599,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
cpy.Splice(tree)(transform(expr))
case TypSplice(expr) =>
cpy.TypSplice(tree)(transform(expr))
case DoWhile(body, cond) =>
cpy.DoWhile(tree)(transform(body), transform(cond))
case ForYield(enums, expr) =>
cpy.ForYield(tree)(transform(enums), transform(expr))
case ForDo(enums, body) =>
Expand Down Expand Up @@ -661,8 +654,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
this(x, expr)
case TypSplice(expr) =>
this(x, expr)
case DoWhile(body, cond) =>
this(this(x, body), cond)
case ForYield(enums, expr) =>
this(this(x, enums), expr)
case ForDo(enums, body) =>
Expand Down
21 changes: 12 additions & 9 deletions compiler/src/dotty/tools/dotc/core/Denotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -802,11 +802,11 @@ object Denotations {
def history: List[SingleDenotation] = {
val b = new ListBuffer[SingleDenotation]
var current = initial
do {
while {
b += (current)
current = current.nextInRun
}
while (current ne initial)
current ne initial
} do ()
b.toList
}

Expand All @@ -820,11 +820,12 @@ object Denotations {
symbol.is(Permanent), // Permanent symbols are valid in all runIds
s"denotation $this invalid in run ${ctx.runId}. ValidFor: $validFor")
var d: SingleDenotation = this
do {
while {
d.validFor = Period(ctx.period.runId, d.validFor.firstPhaseId, d.validFor.lastPhaseId)
d.invalidateInheritedInfo()
d = d.nextInRun
} while (d ne this)
d ne this
} do ()
this
}

Expand Down Expand Up @@ -1053,12 +1054,13 @@ object Denotations {
var cur = this
var cnt = 0
var interval = validFor
do {
while {
cur = cur.nextInRun
cnt += 1
assert(cnt <= MaxPossiblePhaseId, demandOutsideDefinedMsg)
interval |= cur.validFor
} while (cur ne this)
cur ne this
} do ()
interval
}

Expand All @@ -1075,12 +1077,13 @@ object Denotations {
var sb = new StringBuilder()
var cur = this
var cnt = 0
do {
while {
sb.append(" " + cur.validFor)
cur = cur.nextInRun
cnt += 1
if (cnt > MaxPossiblePhaseId) { sb.append(" ..."); cur = this }
} while (cur ne this)
cur ne this
} do ()
sb.toString
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/core/Scopes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -382,9 +382,9 @@ object Scopes {
override final def lookupNextEntry(entry: ScopeEntry)(implicit ctx: Context): ScopeEntry = {
var e = entry
if (hashTable ne null)
do { e = e.tail } while ((e ne null) && e.name != entry.name)
while ({ e = e.tail ; (e ne null) && e.name != entry.name }) ()
else
do { e = e.prev } while ((e ne null) && e.name != entry.name)
while ({ e = e.prev ; (e ne null) && e.name != entry.name }) ()
e
}

Expand Down
5 changes: 3 additions & 2 deletions compiler/src/dotty/tools/dotc/core/tasty/TastyBuffer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,12 @@ class TastyBuffer(initialSize: Int) {
var b = 0L
var x = 0L
var idx = at.index
do {
while {
b = bytes(idx)
x = (x << 7) | (b & 0x7f)
idx += 1
} while ((b & 0x80) == 0)
(b & 0x80) == 0
} do ()
x
}

Expand Down
5 changes: 3 additions & 2 deletions compiler/src/dotty/tools/dotc/core/tasty/TastyReader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,12 @@ class TastyReader(val bytes: Array[Byte], start: Int, end: Int, val base: Int =
def readLongNat(): Long = {
var b = 0L
var x = 0L
do {
while {
b = bytes(bp)
x = (x << 7) | (b & 0x7f)
bp += 1
} while ((b & 0x80) == 0)
(b & 0x80) == 0
} do ()
x
}

Expand Down
5 changes: 3 additions & 2 deletions compiler/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,11 @@ class TreeBuffer extends TastyBuffer(50000) {
//println(s"offsets: ${offsets.take(numOffsets).deep}")
//println(s"deltas: ${delta.take(numOffsets).deep}")
var saved = 0
do {
while {
saved = adjustDeltas()
pickling.println(s"adjusting deltas, saved = $saved")
} while (saved > 0 && length / saved < 100)
saved > 0 && length / saved < 100
} do ()
adjustOffsets()
adjustTreeAddrs()
val wasted = compress()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,11 @@ class PickleBuffer(data: Array[Byte], from: Int, to: Int) {
def readLongNat(): Long = {
var b = 0L
var x = 0L
do {
while ({
b = readByte()
x = (x << 7) + (b & 0x7f)
} while ((b & 0x80) != 0L)
(b & 0x80) != 0L
}) ()
x
}

Expand Down
6 changes: 4 additions & 2 deletions compiler/src/dotty/tools/dotc/parsing/CharArrayReader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,10 @@ abstract class CharArrayReader { self =>
}
}
if (charOffset < buf.length && buf(charOffset) == 'u' && decodeUni && evenSlashPrefix) {
do charOffset += 1
while (charOffset < buf.length && buf(charOffset) == 'u')
while {
charOffset += 1
charOffset < buf.length && buf(charOffset) == 'u'
} do ()
val code = udigit << 12 | udigit << 8 | udigit << 4 | udigit
lastUnicodeOffset = charOffset
ch = code.toChar
Expand Down
5 changes: 3 additions & 2 deletions compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ object JavaParsers {
def skipAhead(): Unit = {
var nparens = 0
var nbraces = 0
do {
while ({
in.token match {
case LPAREN =>
nparens += 1
Expand All @@ -157,7 +157,8 @@ object JavaParsers {
nbraces -= 1
case _ =>
}
} while (in.token != EOF && (nparens > 0 || nbraces > 0))
in.token != EOF && (nparens > 0 || nbraces > 0)
}) ()
}

def skipTo(tokens: Int*): Unit = {
Expand Down
45 changes: 27 additions & 18 deletions compiler/src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -301,9 +301,6 @@ object Parsers {
def deprecationWarning(msg: => Message, offset: Int = in.offset): Unit =
ctx.deprecationWarning(msg, source.atSpan(Span(offset)))

def errorOrMigrationWarning(msg: => Message, offset: Int = in.offset): Unit =
ctx.errorOrMigrationWarning(msg, source.atSpan(Span(offset)))

/** Issue an error at current offset that input is incomplete */
def incompleteInputError(msg: => Message): Unit =
ctx.incompleteInputError(msg, source.atSpan(Span(in.offset)))
Expand Down Expand Up @@ -392,12 +389,6 @@ object Parsers {
finally staged = saved
}

def migrationWarningOrError(msg: String, offset: Int = in.offset): Unit =
if (in.isScala2Mode)
ctx.migrationWarning(msg, source.atSpan(Span(offset)))
else
syntaxError(msg, offset)

/* ---------- TREE CONSTRUCTION ------------------------------------------- */

/** Convert tree to formal parameter list
Expand Down Expand Up @@ -780,9 +771,9 @@ object Parsers {
Quote(t)
}
else {
migrationWarningOrError(em"""symbol literal '${in.name} is no longer supported,
|use a string literal "${in.name}" or an application Symbol("${in.name}") instead,
|or enclose in braces '{${in.name}} if you want a quoted expression.""")
in.errorOrMigrationWarning(em"""symbol literal '${in.name} is no longer supported,
|use a string literal "${in.name}" or an application Symbol("${in.name}") instead,
|or enclose in braces '{${in.name}} if you want a quoted expression.""")
if (in.isScala2Mode) {
patch(source, Span(in.offset, in.offset + 1), "Symbol(\"")
patch(source, Span(in.charOffset - 1), "\")")
Expand Down Expand Up @@ -1216,7 +1207,7 @@ object Parsers {
AppliedTypeTree(toplevelTyp(), Ident(pname))
} :: contextBounds(pname)
case VIEWBOUND =>
errorOrMigrationWarning("view bounds `<%' are deprecated, use a context bound `:' instead")
in.errorOrMigrationWarning("view bounds `<%' are deprecated, use a context bound `:' instead")
atSpan(in.skipToken()) {
Function(Ident(pname) :: Nil, toplevelTyp())
} :: contextBounds(pname)
Expand Down Expand Up @@ -1339,12 +1330,30 @@ object Parsers {
WhileDo(cond, body)
}
case DO =>
atSpan(in.skipToken()) {
in.errorOrMigrationWarning(
i"""`do <body> while <cond>' is no longer supported,
|use `while {<body> ; <cond>} do ()' instead.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure we discussed today that this PR shouldn't be mixed up with that possible future syntax. Hence I believe we should suggest while ({ body; cond }) () here instead.

|The statement can be rewritten automatically under -language:Scala2 -migration -rewrite.
""")
val start = in.skipToken()
atSpan(start) {
val body = expr()
if (isStatSep) in.nextToken()
val whileStart = in.offset
accept(WHILE)
val cond = expr()
DoWhile(body, cond)
if (ctx.settings.migration.value) {
patch(source, Span(start, start + 2), "while ({")
patch(source, Span(whileStart, whileStart + 5), ";")
cond match {
case Parens(_) =>
patch(source, Span(cond.span.start, cond.span.start + 1), "")
patch(source, Span(cond.span.end - 1, cond.span.end), "")
case _ =>
}
patch(source, cond.span.endPos, "}) ()")
}
WhileDo(Block(body :: Nil, cond), Literal(Constant(())))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is incorrect, as both body and block could define symbols with the same name. If they are put together in a single Block, the scopes will clash.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will need a test for this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, body and cond are already blocks if they have definitions. I added some tests in #7002. Did I miss some other definitions that could be represented differently?

}
case TRY =>
val tryOffset = in.offset
Expand Down Expand Up @@ -1525,7 +1534,7 @@ object Parsers {
if (ctx.settings.strict.value)
// Don't error in non-strict mode, as the alternative syntax "implicit (x: T) => ... "
// is not supported by Scala2.x
migrationWarningOrError(s"This syntax is no longer supported; parameter needs to be enclosed in (...)")
in.errorOrMigrationWarning(s"This syntax is no longer supported; parameter needs to be enclosed in (...)")
in.nextToken()
val t = infixType()
if (false && in.isScala2Mode) {
Expand Down Expand Up @@ -1933,15 +1942,15 @@ object Parsers {
infixPattern() match {
case pt @ Ident(tpnme.WILDCARD_STAR) =>
if (ctx.settings.strict.value)
migrationWarningOrError("The syntax `x @ _*' is no longer supported; use `x : _*' instead", startOffset(p))
in.errorOrMigrationWarning("The syntax `x @ _*' is no longer supported; use `x : _*' instead", Span(startOffset(p)))
atSpan(startOffset(p), offset) { Typed(p, pt) }
case pt =>
atSpan(startOffset(p), 0) { Bind(name, pt) }
}
case p @ Ident(tpnme.WILDCARD_STAR) =>
// compatibility for Scala2 `_*` syntax
if (ctx.settings.strict.value)
migrationWarningOrError("The syntax `_*' is no longer supported; use `x : _*' instead", startOffset(p))
in.errorOrMigrationWarning("The syntax `_*' is no longer supported; use `x : _*' instead", Span(startOffset(p)))
atSpan(startOffset(p)) { Typed(Ident(nme.WILDCARD), p) }
case p =>
p
Expand Down
20 changes: 12 additions & 8 deletions compiler/src/dotty/tools/dotc/parsing/Scanners.scala
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ object Scanners {
skipComment()
}
else if (ch == '*') {
do nextChar() while (ch == '*')
while ({ nextChar() ; ch == '*' }) ()
if (ch == '/') nextChar()
else skipComment()
}
Expand Down Expand Up @@ -703,17 +703,20 @@ object Scanners {
/** Is the token following the current one in `tokens`? */
def lookaheadIn(tokens: BitSet): Boolean = {
val lookahead = lookaheadScanner
do lookahead.nextToken()
while (lookahead.token == NEWLINE || lookahead.token == NEWLINES)
while ({
lookahead.nextToken()
lookahead.token == NEWLINE || lookahead.token == NEWLINES
}) ()
tokens.contains(lookahead.token)
}

/** Is the current token in a position where a modifier is allowed? */
def inModifierPosition(): Boolean = {
val lookahead = lookaheadScanner
do lookahead.nextToken()
while (lookahead.token == NEWLINE || lookahead.token == NEWLINES ||
lookahead.isSoftModifier)
while ({
lookahead.nextToken()
lookahead.token == NEWLINE || lookahead.token == NEWLINES || lookahead.isSoftModifier
}) ()
modifierFollowers.contains(lookahead.token)
}

Expand Down Expand Up @@ -866,10 +869,11 @@ object Scanners {
next.token = LBRACE
} else if (Character.isUnicodeIdentifierStart(ch) || ch == '_') {
finishStringPart()
do {
while ({
putChar(ch)
nextRawChar()
} while (ch != SU && Character.isUnicodeIdentifierPart(ch))
ch != SU && Character.isUnicodeIdentifierPart(ch)
}) ()
finishNamed(target = next)
} else {
error("invalid string interpolation: `$$', `$'ident or `$'BlockExpr expected")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,7 @@ private[dotty] trait MarkupParserCommon {

val buf = new StringBuilder

do buf append ch_returning_nextch
while (isNameChar(ch))
while ({ buf append ch_returning_nextch ; isNameChar(ch) }) ()

if (buf.last == ':') {
reportSyntaxError( "name cannot end in ':'" )
Expand Down
Loading