diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 744274c9266d..fa342d56e6af 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -156,12 +156,17 @@ object Parsers { def skipBraces(): Unit = { accept(if (in.token == INDENT) INDENT else LBRACE) var openBraces = 1 - while (in.token != EOF && openBraces > 0) - skipBracesHook() getOrElse { - if (in.token == LBRACE || in.token == INDENT) openBraces += 1 - else if (in.token == RBRACE || in.token == OUTDENT) openBraces -= 1 - in.nextToken() - } + val savedCheckEndMarker = in.checkEndMarker + try + in.checkEndMarker = false + while (in.token != EOF && openBraces > 0) + skipBracesHook() getOrElse { + if (in.token == LBRACE || in.token == INDENT) openBraces += 1 + else if (in.token == RBRACE || in.token == OUTDENT) openBraces -= 1 + in.nextToken() + } + finally + in.checkEndMarker = savedCheckEndMarker } } diff --git a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala index 665258a15050..b7001bbdc5b2 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala @@ -54,6 +54,9 @@ object Scanners { /** the base of a number */ var base: Int = 0 + /** Set to false to disable end marker alignment checks, used for outline parsing. */ + var checkEndMarker: Boolean = true + def copyFrom(td: TokenData): Unit = { this.token = td.token this.offset = td.offset @@ -331,10 +334,12 @@ object Scanners { def endMarkerScope[T](tag: EndMarkerTag)(op: => T): T = val saved = openEndMarkers openEndMarkers = (tag, currentRegion.indentWidth) :: openEndMarkers - try op finally openEndMarkers = saved + try op + finally openEndMarkers = saved /** If this token and the next constitute an end marker, skip them and check they - * align with an opening construct with the same end marker tag. + * align with an opening construct with the same end marker tag, + * unless `checkEndMarker` is false. */ protected def skipEndMarker(width: IndentWidth): Unit = if next.token == IDENTIFIER && next.name == nme.end then @@ -348,8 +353,9 @@ object Scanners { openEndMarkers = rest checkAligned() case _ => - lexical.println(i"misaligned end marker $tag, $width, $openEndMarkers") - errorButContinue("misaligned end marker", start) + if checkEndMarker + lexical.println(i"misaligned end marker $tag, $width, $openEndMarkers") + errorButContinue("misaligned end marker", start) val skipTo = lookahead.charOffset lookahead.nextToken() diff --git a/compiler/test/dotty/tools/dotc/CompilationTests.scala b/compiler/test/dotty/tools/dotc/CompilationTests.scala index d2b56a7d0731..cf50445a170b 100644 --- a/compiler/test/dotty/tools/dotc/CompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/CompilationTests.scala @@ -39,9 +39,7 @@ class CompilationTests extends ParallelTesting { compileFile("tests/pos-scala2/rewrites.scala", scala2CompatMode.and("-rewrite")).copyToTarget(), compileFile("tests/pos-special/utf8encoded.scala", explicitUTF8), compileFile("tests/pos-special/utf16encoded.scala", explicitUTF16), - compileFile("tests/pos-special/sourcepath/outer/Test.scala", defaultOptions.and("-sourcepath", "tests/pos-special/sourcepath")), - compileFile("tests/pos-special/sourcepath/outer/Test2.scala", defaultOptions.and("-sourcepath", "tests/pos-special/sourcepath")), - compileFile("tests/pos-special/sourcepath/outer/Test3.scala", defaultOptions.and("-sourcepath", "tests/pos-special/sourcepath")), + compileFilesInDir("tests/pos-special/sourcepath/outer", defaultOptions.and("-sourcepath", "tests/pos-special/sourcepath")), compileFile("tests/pos-special/sourcepath/outer/nested/Test4.scala", defaultOptions.and("-sourcepath", "tests/pos-special/sourcepath")), compileFilesInDir("tests/pos-special/fatal-warnings", defaultOptions.and("-Xfatal-warnings", "-feature")), compileFilesInDir("tests/pos-special/spec-t5545", defaultOptions), diff --git a/tests/pos-special/sourcepath/outer/indent2.scala b/tests/pos-special/sourcepath/outer/indent2.scala new file mode 100644 index 000000000000..354b92601e05 --- /dev/null +++ b/tests/pos-special/sourcepath/outer/indent2.scala @@ -0,0 +1,7 @@ +package outer +import nested._ + +object indent2 { + val x2: Int = indent1.inner.x + val y2: Int = indent1.y +} diff --git a/tests/pos-special/sourcepath/outer/nested/BC.scala b/tests/pos-special/sourcepath/outer/nested/BC.scala index f6d0fedd4825..73c5416c6e9d 100644 --- a/tests/pos-special/sourcepath/outer/nested/BC.scala +++ b/tests/pos-special/sourcepath/outer/nested/BC.scala @@ -1,6 +1,6 @@ package outer.nested -case class B(x: Int) extends A(x) +case class B(override val x: Int) extends A(x) case class C(s: String) extends A(s.length) diff --git a/tests/pos-special/sourcepath/outer/nested/indent1.scala b/tests/pos-special/sourcepath/outer/nested/indent1.scala new file mode 100644 index 000000000000..896ebedc8d4c --- /dev/null +++ b/tests/pos-special/sourcepath/outer/nested/indent1.scala @@ -0,0 +1,9 @@ +package outer +package nested + +object indent1 + object inner with + def x: Int = 1 + end inner + val y: Int = 2 +end indent1