Skip to content

Commit 13e7b71

Browse files
committed
Enable significant indentation inside braces.
Also: Make indentation opt in, controlled by -indent. -indent is set as a default option when testing.
1 parent 80a7d1d commit 13e7b71

File tree

4 files changed

+48
-38
lines changed

4 files changed

+48
-38
lines changed

compiler/src/dotty/tools/dotc/config/Config.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ object Config {
158158
final val simplifyApplications = true
159159

160160
/** Always assume -indent */
161-
final val allowIndent = true
161+
final val alwaysIndent = false
162162

163163
/** If set, prints a trace of all symbol completions */
164164
final val showCompletions = false

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

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -708,9 +708,8 @@ object Parsers {
708708
val isOutermost = in.currentRegion.isOutermost
709709
val savedPending = pendingPatches
710710
def allBraces(r: Region): Boolean = r match {
711-
case Outermost => true
712-
case InBraces(outer) => allBraces(outer)
713-
case _ => false
711+
case r: InBraces => allBraces(r.enclosing)
712+
case _ => r.isOutermost
714713
}
715714
var canRewrite = allBraces(in.currentRegion) && // test (1)
716715
!testChars(in.lastOffset - 3, " =>") // test(6)
@@ -1290,6 +1289,7 @@ object Parsers {
12901289
}
12911290
else { accept(TLARROW); typ() }
12921291
}
1292+
else if (in.token == INDENT) enclosed(INDENT, typ())
12931293
else infixType()
12941294

12951295
in.token match {
@@ -2160,8 +2160,15 @@ object Parsers {
21602160
def block(): Tree = {
21612161
val stats = blockStatSeq()
21622162
def isExpr(stat: Tree) = !(stat.isDef || stat.isInstanceOf[Import])
2163-
if (stats.nonEmpty && isExpr(stats.last)) Block(stats.init, stats.last)
2164-
else Block(stats, EmptyTree)
2163+
stats match {
2164+
case (stat : Block) :: Nil =>
2165+
stat // A typical case where this happens is creating a block around a region
2166+
// hat is already indented, e.g. something following a =>.
2167+
case _ :: stats1 if isExpr(stats.last) =>
2168+
Block(stats.init, stats.last)
2169+
case _ =>
2170+
Block(stats, EmptyTree)
2171+
}
21652172
}
21662173

21672174
/** Guard ::= if PostfixExpr

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

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ object Scanners {
234234
val newSyntax = ctx.settings.newSyntax.value
235235

236236
val noindentSyntax = ctx.settings.noindent.value
237-
val indentSyntax = Config.allowIndent || ctx.settings.indent.value || noindentSyntax && rewrite
237+
val indentSyntax = Config.alwaysIndent || ctx.settings.indent.value || noindentSyntax && rewrite
238238
val rewriteToIndent = ctx.settings.indent.value && rewrite
239239
val rewriteNoIndent = noindentSyntax && rewrite
240240

@@ -352,15 +352,16 @@ object Scanners {
352352
case LPAREN | LBRACKET =>
353353
currentRegion = InParens(lastToken, currentRegion)
354354
case LBRACE =>
355-
currentRegion = InBraces(currentRegion)
355+
currentRegion = InBraces(null, currentRegion)
356356
case RBRACE =>
357357
def dropBraces(): Unit = currentRegion match {
358-
case Outermost =>
359-
case InBraces(outer) =>
360-
currentRegion = outer
358+
case r: InBraces =>
359+
currentRegion = r.enclosing
361360
case _ =>
362-
currentRegion = currentRegion.enclosing
363-
dropBraces()
361+
if (!currentRegion.isOutermost) {
362+
currentRegion = currentRegion.enclosing
363+
dropBraces()
364+
}
364365
}
365366
dropBraces()
366367
case RPAREN | RBRACKET =>
@@ -566,42 +567,44 @@ object Scanners {
566567
var newlineIsSeparating = false
567568
var lastWidth = IndentWidth.Zero
568569
var indentPrefix = EMPTY
570+
val nextWidth = indentWidth(offset)
569571
currentRegion match {
570-
case Outermost =>
571-
if (indentSyntax) indentIsSignificant = true
572-
newlineIsSeparating = true
573572
case r: Indented =>
574-
indentIsSignificant = true
575-
newlineIsSeparating = true
573+
indentIsSignificant = indentSyntax
576574
lastWidth = r.width
575+
newlineIsSeparating = lastWidth <= nextWidth
577576
indentPrefix = r.prefix
578-
case _: InBraces =>
577+
case r: InBraces =>
578+
indentIsSignificant = indentSyntax
579+
if (r.width == null) r.width = nextWidth
580+
lastWidth = r.width
579581
newlineIsSeparating = true
582+
indentPrefix = LBRACE
580583
case _ =>
581584
}
582-
val nextWidth = indentWidth(offset)
583585
if (newlineIsSeparating &&
584-
canEndStatTokens.contains(lastToken)&&
586+
canEndStatTokens.contains(lastToken) &&
585587
canStartStatTokens.contains(token) &&
586-
(!indentIsSignificant || lastWidth <= nextWidth) &&
587588
!isLeadingInfixOperator())
588589
insert(if (pastBlankLine) NEWLINES else NEWLINE, lineOffset)
589590
else if (indentIsSignificant) {
590-
if (lastWidth < nextWidth ||
591-
lastWidth == nextWidth && (lastToken == MATCH || lastToken == CATCH) && token == CASE) {
591+
if (nextWidth < lastWidth
592+
|| nextWidth == lastWidth && (indentPrefix == MATCH || indentPrefix == CATCH) && token != CASE) {
593+
currentRegion match {
594+
case r: Indented if !r.isOutermost && !isLeadingInfixOperator() =>
595+
currentRegion = r.enclosing
596+
insert(OUTDENT, offset)
597+
handleEndMarkers(nextWidth)
598+
case _ =>
599+
}
600+
}
601+
else if (lastWidth < nextWidth ||
602+
lastWidth == nextWidth && (lastToken == MATCH || lastToken == CATCH) && token == CASE) {
592603
if (canStartIndentTokens.contains(lastToken)) {
593604
currentRegion = Indented(nextWidth, Set(), lastToken, currentRegion)
594605
insert(INDENT, offset)
595606
}
596607
}
597-
else if (nextWidth < lastWidth ||
598-
nextWidth == lastWidth && (indentPrefix == MATCH || indentPrefix == CATCH) && token != CASE) {
599-
if (!isLeadingInfixOperator()) {
600-
currentRegion = currentRegion.asInstanceOf[Indented].enclosing
601-
insert(OUTDENT, offset)
602-
handleEndMarkers(nextWidth)
603-
}
604-
}
605608
else if (lastWidth != nextWidth)
606609
errorButContinue(
607610
i"""Incompatible combinations of tabs and spaces in indentation prefixes.
@@ -661,9 +664,9 @@ object Scanners {
661664
val atEOL = isAfterLineEnd
662665
reset()
663666
if (atEOL) token = COLONEOL
664-
case EOF =>
667+
case EOF | RBRACE =>
665668
currentRegion match {
666-
case r: Indented =>
669+
case r: Indented if !r.isOutermost =>
667670
insert(OUTDENT, offset)
668671
currentRegion = r.outer
669672
case _ =>
@@ -1368,16 +1371,16 @@ object Scanners {
13681371
def enclosing: Region = outer.asInstanceOf[Region]
13691372
}
13701373
case class InParens(prefix: Token, outer: Region) extends Region
1371-
case class InBraces(outer: Region) extends Region
1374+
case class InBraces(var width: IndentWidth | Null, outer: Region) extends Region
13721375
case class InString(multiLine: Boolean, outer: Region) extends Region
13731376

13741377
/** A class describing an indentation region.
13751378
* @param width The principal indendation width
13761379
* @param others Other indendation widths > width of lines in the same region
13771380
*/
1378-
case class Indented(width: IndentWidth, others: Set[IndentWidth], prefix: Token, outer: Region) extends Region
1381+
case class Indented(width: IndentWidth, others: Set[IndentWidth], prefix: Token, outer: Region | Null) extends Region
13791382

1380-
case object Outermost extends Region { val outer = null }
1383+
val Outermost = Indented(IndentWidth.Zero, Set(), EMPTY, null)
13811384

13821385
enum IndentWidth {
13831386
case Run(ch: Char, n: Int)

compiler/test/dotty/tools/vulpix/TestConfiguration.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ object TestConfiguration {
4444

4545
val yCheckOptions = Array("-Ycheck:all")
4646

47-
val commonOptions = checkOptions ++ noCheckOptions ++ yCheckOptions
47+
val commonOptions = Array("-indent") ++ checkOptions ++ noCheckOptions ++ yCheckOptions
4848
val defaultOptions = TestFlags(basicClasspath, commonOptions)
4949
val withCompilerOptions =
5050
defaultOptions.withClasspath(withCompilerClasspath).withRunClasspath(withCompilerClasspath)

0 commit comments

Comments
 (0)