From 0aab150242a03e76c4212ff6c500dfdcb4fbe518 Mon Sep 17 00:00:00 2001 From: Vadim Chelyshov Date: Tue, 24 Aug 2021 20:27:24 +0300 Subject: [PATCH] Collective extensions is sensitive to EOF This allows REPL to input extensions. --- compiler/src/dotty/tools/dotc/parsing/Parsers.scala | 13 +++++++++---- .../test/dotty/tools/repl/ReplCompilerTests.scala | 6 ++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 82b4692773ab..c71119c062e7 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -3652,7 +3652,7 @@ object Parsers { in.observeIndented() newLineOptWhenFollowedBy(LBRACE) if in.isNestedStart then inDefScopeBraces(extMethods(nparams)) - else { syntaxError("Extension without extension methods"); Nil } + else { syntaxErrorOrIncomplete("Extension without extension methods") ; Nil } val result = atSpan(start)(ExtMethods(joinParams(tparams, leadParamss.toList), methods)) val comment = in.getDocComment(start) if comment.isDefined then @@ -3674,10 +3674,15 @@ object Parsers { def extMethods(numLeadParams: Int): List[DefDef] = checkNoEscapingPlaceholders { val meths = new ListBuffer[DefDef] while - meths += extMethod(numLeadParams) - statSepOrEnd(meths, what = "extension method") + val start = in.offset + val mods = defAnnotsMods(modifierTokens) + in.token != EOF && { + accept(DEF) + meths += defDefOrDcl(start, mods, numLeadParams) + in.token != EOF && statSepOrEnd(meths, what = "extension method") + } do () - if meths.isEmpty then syntaxError("`def` expected") + if meths.isEmpty then syntaxErrorOrIncomplete("`def` expected") meths.toList } diff --git a/compiler/test/dotty/tools/repl/ReplCompilerTests.scala b/compiler/test/dotty/tools/repl/ReplCompilerTests.scala index d42052e4fb52..87c493ecde6a 100644 --- a/compiler/test/dotty/tools/repl/ReplCompilerTests.scala +++ b/compiler/test/dotty/tools/repl/ReplCompilerTests.scala @@ -199,6 +199,12 @@ class ReplCompilerTests extends ReplTest { assertFalse(ParseResult.isIncomplete("_ + 1")) // was: assertThrows[NullPointerException] } + @Test def `i9374 accept collective extensions`: Unit = fromInitialState { state => + given Context = state.context + assert(ParseResult.isIncomplete("extension (x: String)")) + assert(ParseResult.isIncomplete("extension (x: String) {")) + } + @Test def testSingletonPrint = fromInitialState { implicit state => run("""val a = "hello"; val x: a.type = a""") assertMultiLineEquals("val a: String = hello\nval x: a.type = hello", storedOutput().trim)