From 0a0cedef5637e042987630ac8f99312491c8de41 Mon Sep 17 00:00:00 2001 From: Jakub Ciesluk <323892@uwr.edu.pl> Date: Thu, 6 Jul 2023 11:05:01 +0200 Subject: [PATCH] fix: Implement all members with end marker --- .../pc/completions/OverrideCompletions.scala | 26 ++++--- .../AutoImplementAbstractMembersSuite.scala | 70 +++++++++++++++++++ 2 files changed, 88 insertions(+), 8 deletions(-) diff --git a/mtags/src/main/scala-3/scala/meta/internal/pc/completions/OverrideCompletions.scala b/mtags/src/main/scala-3/scala/meta/internal/pc/completions/OverrideCompletions.scala index a75cc13cc4f..e6a6f25a737 100644 --- a/mtags/src/main/scala-3/scala/meta/internal/pc/completions/OverrideCompletions.scala +++ b/mtags/src/main/scala-3/scala/meta/internal/pc/completions/OverrideCompletions.scala @@ -317,8 +317,8 @@ object OverrideCompletions: .sortBy(_.sourcePos.start) val source = indexedContext.ctx.source - val shouldCompleteBraces = decls.isEmpty && hasBraces(text, defn).isEmpty - + val shouldCompleteBraces = + decls.isEmpty && hasBracesOrColon(text, defn).isEmpty val (startIndent, indent, lastIndent) = calcIndent(defn, decls, source, text, shouldCompleteBraces) @@ -475,7 +475,7 @@ object OverrideCompletions: private def inferEditPosition(text: String, defn: TargetDef)(using Context ): SourcePosition = - val span = hasBraces(text, defn) + val span = hasBracesOrColon(text, defn) .map { offset => defn.sourcePos.span.withStart(offset + 1).withEnd(offset + 1) } @@ -485,7 +485,9 @@ object OverrideCompletions: defn.sourcePos.withSpan(span) end inferEditPosition - private def hasBraces(text: String, defn: TargetDef): Option[Int] = + private def hasBracesOrColon(text: String, defn: TargetDef)(using + Context + ): Option[Int] = def hasSelfTypeAnnot = defn match case td: TypeDef => td.rhs match @@ -494,12 +496,20 @@ object OverrideCompletions: case _ => false case _ => false val start = defn.span.start - val offset = + val braceOffset = if hasSelfTypeAnnot then text.indexOf("=>", start) + 1 else text.indexOf("{", start) - if offset > 0 && offset < defn.span.end then Some(offset) - else None - end hasBraces + if braceOffset > 0 && braceOffset < defn.span.end then Some(braceOffset) + else hasColon(text, defn) + end hasBracesOrColon + + private def hasColon(text: String, defn: TargetDef)(using + Context + ): Option[Int] = + defn match + case td: TypeDef if text.charAt(td.rhs.span.end) == ':' => + Some(td.rhs.span.end) + case _ => None private def fallbackFromParent(parent: Tree, name: String)(using Context) = val stats = parent match diff --git a/tests/cross/src/test/scala/tests/pc/AutoImplementAbstractMembersSuite.scala b/tests/cross/src/test/scala/tests/pc/AutoImplementAbstractMembersSuite.scala index 50dbc9db5df..8650f913005 100644 --- a/tests/cross/src/test/scala/tests/pc/AutoImplementAbstractMembersSuite.scala +++ b/tests/cross/src/test/scala/tests/pc/AutoImplementAbstractMembersSuite.scala @@ -1201,6 +1201,76 @@ class AutoImplementAbstractMembersSuite extends BaseCodeActionSuite { |""".stripMargin, ) + checkEdit( + "end-marker".tag(IgnoreScala2), + """|package a + | + |object A { + | trait Base: + | def foo(x: Int): Int + | def bar(x: String): String + | + | class <> extends Base: + | + | end Concrete + | + |} + |""".stripMargin, + """|package a + | + |object A { + | trait Base: + | def foo(x: Int): Int + | def bar(x: String): String + | + | class Concrete extends Base: + | + | override def foo(x: Int): Int = ??? + | + | override def bar(x: String): String = ??? + | + | + | end Concrete + | + |} + |""".stripMargin, + ) + + checkEdit( + "end-marker2".tag(IgnoreScala2), + """|package a + | + |object A { + | trait Base: + | def foo(x: Int): Int + | def bar(x: String): String + | + | class <>(x: Int, y: String) extends Base: + | + | end Concrete + | + |} + |""".stripMargin, + """|package a + | + |object A { + | trait Base: + | def foo(x: Int): Int + | def bar(x: String): String + | + | class Concrete(x: Int, y: String) extends Base: + | + | override def foo(x: Int): Int = ??? + | + | override def bar(x: String): String = ??? + | + | + | end Concrete + | + |} + |""".stripMargin, + ) + def checkEdit( name: TestOptions, original: String,