From f0e24ab7c071318d2119d0682f9d7400c35299c3 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 15 Oct 2019 21:05:08 +0200 Subject: [PATCH 1/4] Fix #7421: Insert missing tokens where a region ends --- compiler/src/dotty/tools/dotc/parsing/Parsers.scala | 1 + compiler/src/dotty/tools/dotc/parsing/Scanners.scala | 7 +++++++ .../reference/other-new-features/indentation-new.md | 2 ++ tests/pos/i7421.scala | 11 +++++++++++ 4 files changed, 21 insertions(+) create mode 100644 tests/pos/i7421.scala diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 4de9b5230f8d..3fcaec91e737 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -348,6 +348,7 @@ object Parsers { if in.isNewLine then in.nextToken() else accept(SEMI) def acceptStatSepUnlessAtEnd(altEnd: Token = EOF): Unit = + in.observeOutdented() if (!isStatSeqEnd) in.token match { case EOF => diff --git a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala index a7513b8a722b..314f4398e6e9 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala @@ -555,6 +555,13 @@ object Scanners { token = INDENT end observeIndented + /** Insert an token if next token is in statCtdTokens */ + def observeOutdented(): Unit = currentRegion match + case r: Indented if !r.isOutermost && closingRegionTokens.contains(token) => + currentRegion = r.enclosing + insert(OUTDENT, offset) + case _ => + /** - Join CASE + CLASS => CASECLASS, CASE + OBJECT => CASEOBJECT, SEMI + ELSE => ELSE, COLON + => COLONEOL * - Insert missing OUTDENTs at EOF */ diff --git a/docs/docs/reference/other-new-features/indentation-new.md b/docs/docs/reference/other-new-features/indentation-new.md index 4d30850fa6a8..700bb973609a 100644 --- a/docs/docs/reference/other-new-features/indentation-new.md +++ b/docs/docs/reference/other-new-features/indentation-new.md @@ -77,6 +77,8 @@ There are two rules: If the indentation width of the token on the next line is still less than the new current indentation width, step (2) repeats. Therefore, several `` tokens may be inserted in a row. + An `` is also inserted if the next statement following a statement sequence starting with an `` closes an indentation region, i.e. is one of `then`, `else`, `do`, `catch`, `finally`, `yield`, `}` or `case`. + It is an error if the indentation width of the token following an `` does not match the indentation of some previous line in the enclosing indentation region. For instance, the following would be rejected. ```scala diff --git a/tests/pos/i7421.scala b/tests/pos/i7421.scala new file mode 100644 index 000000000000..8e2b5962fc18 --- /dev/null +++ b/tests/pos/i7421.scala @@ -0,0 +1,11 @@ +object Main { + + def main(args: Array[String]): Unit = { + if (args.length > 0) then + { + println(args) + } else { + println("Hello world!") + } + } +} \ No newline at end of file From 857c8749959cff9e9c8e72466b2f5d557f69ef52 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 15 Oct 2019 21:31:42 +0200 Subject: [PATCH 2/4] Fix neg test --- tests/neg/spaces-vs-tabs.check | 6 +----- tests/neg/spaces-vs-tabs.scala | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/neg/spaces-vs-tabs.check b/tests/neg/spaces-vs-tabs.check index 3827221ff95c..51c2689f57bc 100644 --- a/tests/neg/spaces-vs-tabs.check +++ b/tests/neg/spaces-vs-tabs.check @@ -17,15 +17,11 @@ | Previous indent : 2 tabs | Latest indent : 1 tab, 2 spaces -- Error: tests/neg/spaces-vs-tabs.scala:8:1 --------------------------------------------------------------------------- -8 | else () // error // error +8 | else () // error | ^ | Incompatible combinations of tabs and spaces in indentation prefixes. | Previous indent : 2 tabs | Latest indent : 1 space --- [E040] Syntax Error: tests/neg/spaces-vs-tabs.scala:8:6 ------------------------------------------------------------- -8 | else () // error // error - | ^ - | ';' expected, but '(' found -- Error: tests/neg/spaces-vs-tabs.scala:14:2 -------------------------------------------------------------------------- 14 | else 2 // error // error | ^ diff --git a/tests/neg/spaces-vs-tabs.scala b/tests/neg/spaces-vs-tabs.scala index cf24f8290904..d30d44c827fe 100644 --- a/tests/neg/spaces-vs-tabs.scala +++ b/tests/neg/spaces-vs-tabs.scala @@ -5,7 +5,7 @@ object Test println(2) // error println(3) // error println(4) // error - else () // error // error + else () // error object Test2 From 46b25f5655ab5a2221d82d7d65422b4a608689c1 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 15 Oct 2019 22:28:30 +0200 Subject: [PATCH 3/4] Fix doc comment --- compiler/src/dotty/tools/dotc/parsing/Scanners.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala index 314f4398e6e9..b426cdcfa201 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala @@ -555,7 +555,7 @@ object Scanners { token = INDENT end observeIndented - /** Insert an token if next token is in statCtdTokens */ + /** Insert an token if next token closes an indentation region */ def observeOutdented(): Unit = currentRegion match case r: Indented if !r.isOutermost && closingRegionTokens.contains(token) => currentRegion = r.enclosing From 5fcb578191433ac091de2106c818765e62c47b28 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 15 Oct 2019 22:30:44 +0200 Subject: [PATCH 4/4] Expand test --- tests/pos/i7421.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/pos/i7421.scala b/tests/pos/i7421.scala index 8e2b5962fc18..247285bdc9b6 100644 --- a/tests/pos/i7421.scala +++ b/tests/pos/i7421.scala @@ -7,5 +7,11 @@ object Main { } else { println("Hello world!") } + if (args.length > 0) + { + println(args) + } else { + println("Hello world!") + } } } \ No newline at end of file