Skip to content

Commit b1b6266

Browse files
committed
Don't require colon after class or object sigs
# Conflicts: # compiler/src/dotty/tools/backend/jvm/GenBCode.scala
1 parent 25af286 commit b1b6266

File tree

8 files changed

+471
-440
lines changed

8 files changed

+471
-440
lines changed

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

Lines changed: 410 additions & 411 deletions
Large diffs are not rendered by default.

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

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,6 +1178,11 @@ object Parsers {
11781178
newLineOptWhenFollowedBy(LBRACE)
11791179
}
11801180

1181+
def possibleTemplateStart(): Unit = {
1182+
in.observeIndented()
1183+
newLineOptWhenFollowedBy(LBRACE)
1184+
}
1185+
11811186
def indentRegion[T](tag: EndMarkerTag)(op: => T): T = {
11821187
val iw = in.currentRegion.indentWidth
11831188
val t = op
@@ -3330,7 +3335,7 @@ object Parsers {
33303335
if (in.token == LPAREN)
33313336
try paramClause(prefix = true) :: Nil
33323337
finally {
3333-
possibleBracesStart()
3338+
possibleTemplateStart()
33343339
if (!in.isNestedStart) syntaxErrorOrIncomplete("`{' expected")
33353340
}
33363341
else Nil
@@ -3348,7 +3353,7 @@ object Parsers {
33483353
DefDef(name, tparams, vparamss, parents.head, expr())
33493354
}
33503355
else {
3351-
possibleBracesStart()
3356+
possibleTemplateStart()
33523357
val (tparams1, vparamss1) =
33533358
if (leadingParamss.nonEmpty)
33543359
(tparams, leadingParamss)
@@ -3448,7 +3453,7 @@ object Parsers {
34483453
*/
34493454
def template(constr: DefDef, isEnum: Boolean = false): Template = {
34503455
val (parents, derived) = inheritClauses()
3451-
possibleBracesStart()
3456+
possibleTemplateStart()
34523457
if (isEnum) {
34533458
val (self, stats) = withinEnum(templateBody())
34543459
Template(constr, parents, derived, self, stats)
@@ -3458,13 +3463,15 @@ object Parsers {
34583463

34593464
/** TemplateOpt = [Template]
34603465
*/
3461-
def templateOpt(constr: DefDef): Template = {
3466+
def templateOpt(constr: DefDef): Template =
34623467
possibleBracesStart()
3463-
if (in.token == EXTENDS || isIdent(nme.derives) || in.isNestedStart)
3468+
if (in.token == EXTENDS || isIdent(nme.derives))
34643469
template(constr)
3465-
else
3466-
Template(constr, Nil, Nil, EmptyValDef, Nil)
3467-
}
3470+
else {
3471+
possibleTemplateStart()
3472+
if (in.isNestedStart) template(constr)
3473+
else Template(constr, Nil, Nil, EmptyValDef, Nil)
3474+
}
34683475

34693476
/** TemplateBody ::= [nl] `{' TemplateStatSeq `}'
34703477
*/
@@ -3496,7 +3503,7 @@ object Parsers {
34963503
def packaging(start: Int): Tree = {
34973504
val pkg = qualId()
34983505
indentRegion(pkg) {
3499-
possibleBracesStart()
3506+
possibleTemplateStart()
35003507
val stats = inDefScopeBraces(topStatSeq())
35013508
makePackaging(start, pkg, stats)
35023509
}
@@ -3702,7 +3709,7 @@ object Parsers {
37023709
else {
37033710
val pkg = qualId()
37043711
indentRegion(pkg) {
3705-
possibleBracesStart()
3712+
possibleTemplateStart()
37063713
if (in.token == EOF)
37073714
ts += makePackaging(start, pkg, List())
37083715
else if (in.isNestedStart) {

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ object Scanners {
372372
def isLeadingInfixOperator() = (
373373
allowLeadingInfixOperators
374374
&& ( token == BACKQUOTED_IDENT
375-
|| token == IDENTIFIER && isOperatorPart(name(name.length - 1)))
375+
|| token == IDENTIFIER && isOperatorPart(name(name.length - 1)))
376376
&& ch == ' '
377377
&& !pastBlankLine
378378
&& {
@@ -531,6 +531,25 @@ object Scanners {
531531
}
532532
}
533533

534+
def observeIndented(): Unit =
535+
if (indentSyntax && isAfterLineEnd && token != INDENT) {
536+
val newLineInserted = token == NEWLINE || token == NEWLINES
537+
val nextOffset = if (newLineInserted) next.offset else offset
538+
val nextWidth = indentWidth(nextOffset)
539+
val lastWidth = currentRegion match {
540+
case r: Indented => r.width
541+
case r: InBraces => r.width
542+
case _ => nextWidth
543+
}
544+
545+
if (lastWidth < nextWidth) {
546+
currentRegion = Indented(nextWidth, Set(), COLONEOL, currentRegion)
547+
if (!newLineInserted) next.copyFrom(this)
548+
offset = nextOffset
549+
token = INDENT
550+
}
551+
}
552+
534553
/** - Join CASE + CLASS => CASECLASS, CASE + OBJECT => CASEOBJECT, SEMI + ELSE => ELSE, COLON + <EOL> => COLONEOL
535554
* - Insert missing OUTDENTs at EOF
536555
*/
@@ -1342,6 +1361,7 @@ object Scanners {
13421361
}
13431362
}
13441363
}
1364+
13451365
object IndentWidth {
13461366
private inline val MaxCached = 40
13471367
private val spaces = Array.tabulate(MaxCached + 1)(new Run(' ', _))

tests/neg/endmarkers.scala

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
object Test:
1+
object Test
22

33
locally:
44
var x = 0
@@ -52,28 +52,28 @@ object Test:
5252
x < 10
5353
do ()
5454

55-
class Test2:
55+
class Test2
5656
self =>
5757
def foo = 1
5858

59-
object x:
59+
object x
6060
new Test2:
6161
override def foo = 2
6262
end new // error: end of statement expected but new found // error: not found: end
6363
def bar = 2 // error: ';' expected, but unindent found
6464
end Test2 // error: misaligned end marker
6565
end Test2
6666

67-
class Test3:
67+
class Test3
6868
self =>
6969
def foo = 1
7070
end Test3 // error: not found: end
7171

7272
import collection.mutable.HashMap
7373

74-
class Coder(words: List[String]):
74+
class Coder(words: List[String])
7575

76-
class Foo:
76+
class Foo
7777
println()
7878
end Foo // error: not found: end
7979

tests/neg/spaces-vs-tabs.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
object Test:
1+
object Test
22

33
if true then
44
println(1) // ok
@@ -7,7 +7,7 @@ object Test:
77
println(4) // error
88
else () // error // error
99

10-
object Test2:
10+
object Test2
1111

1212
if true then
1313
1

tests/pos/indent.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
object Test:
1+
object Test
22

33
locally:
44
var x = 0
@@ -56,7 +56,7 @@ object Test:
5656
x < 10
5757
do ()
5858

59-
class Test2:
59+
class Test2
6060
self =>
6161
def foo = 1
6262

@@ -67,15 +67,15 @@ class Test2:
6767
end x
6868
end Test2
6969

70-
class Test3:
70+
class Test3
7171
self =>
7272
def foo = 1
7373

7474
import collection.mutable.HashMap
7575

76-
class Coder(words: List[String]):
76+
class Coder(words: List[String])
7777

78-
class Foo:
78+
class Foo
7979
println()
8080
end Foo
8181

tests/pos/indent2.scala

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1-
object testindent:
2-
if 1 > 0 then
1+
object testindent
2+
3+
class C
4+
val x = 0
5+
6+
val c = new C
7+
if 1 > c.x then
38
println
49
println
510
else
611
println
7-
println
12+
println

tests/run/tcpoly_parseridioms.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ trait Parsers {
55
type Input = List[Char]
66

77
sealed class ParseResult[+t](val next: Input)
8-
case class Success[+t](override val next: Input, result: t) extends ParseResult[t](next)
9-
case class Failure(override val next: Input, msg: String) extends ParseResult[Nothing](next)
8+
case class Success[+t](override val next: Input, result: t) extends ParseResult[t](next)
9+
case class Failure(override val next: Input, msg: String) extends ParseResult[Nothing](next)
1010

1111
abstract class Parser[+t] {
1212
def apply(in: Input): ParseResult[t]

0 commit comments

Comments
 (0)