From 78b6dbd028e1f4b1fa7ad534f6e18a73a1f3c345 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Fa=C5=82drowicz?= Date: Fri, 1 Aug 2025 14:04:09 +0200 Subject: [PATCH 1/2] additional completions for using clause --- .../pc/completions/CompletionAffix.scala | 3 +- .../tools/pc/completions/Completions.scala | 16 ++++- .../tests/completion/CompletionArgSuite.scala | 59 +++++++++++++++++++ 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionAffix.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionAffix.scala index 4ed58c773a7c..78f9f5f68bfb 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionAffix.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionAffix.scala @@ -56,6 +56,7 @@ case class CompletionAffix( private def loopPrefix(prefixes: List[PrefixKind]): String = prefixes match case PrefixKind.New :: tail => "new " + loopPrefix(tail) + case PrefixKind.Using :: tail => "using " + loopPrefix(tail) case _ => "" /** @@ -87,7 +88,7 @@ enum SuffixKind: case Brace, Bracket, Template, NoSuffix enum PrefixKind: - case New + case New, Using type Suffix = Affix[SuffixKind] type Prefix = Affix[PrefixKind] diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala index b396dd780cc0..5d816c96706e 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala @@ -193,13 +193,23 @@ class Completions( ) end isAbstractType - private def findSuffix(symbol: Symbol): CompletionAffix = + private def findSuffix(symbol: Symbol, adjustedPath: List[untpd.Tree]): CompletionAffix = CompletionAffix.empty .chain { suffix => // for [] suffix if shouldAddSuffix && symbol.info.typeParams.nonEmpty then suffix.withNewSuffixSnippet(Affix(SuffixKind.Bracket)) else suffix } + .chain{ suffix => + adjustedPath match + case (ident: Ident) :: (app@Apply(_,args)) :: _ if args.size == 1 => + app.symbol.info match + case mt@MethodType(termNames) if app.symbol.paramSymss.last.exists(_.is(Given)) => + suffix.withNewPrefix(Affix(PrefixKind.Using)) + case _ => suffix + case _ => suffix + + } .chain { suffix => // for () suffix if shouldAddSuffix && symbol.is(Flags.Method) then val paramss = getParams(symbol) @@ -271,7 +281,7 @@ class Completions( val existsApply = extraMethodDenots.exists(_.symbol.name == nme.apply) extraMethodDenots.map { methodDenot => - val suffix = findSuffix(methodDenot.symbol) + val suffix = findSuffix(methodDenot.symbol, adjustedPath) val affix = if methodDenot.symbol.isConstructor && existsApply then adjustedPath match case (select @ Select(qual, _)) :: _ => @@ -293,7 +303,7 @@ class Completions( if skipOriginalDenot then extraCompletionValues else - val suffix = findSuffix(denot.symbol) + val suffix = findSuffix(denot.symbol, adjustedPath) val name = undoBacktick(label) val denotCompletionValue = toCompletionValue(name, denot, suffix) denotCompletionValue :: extraCompletionValues diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionArgSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionArgSuite.scala index 044b5456d31d..1420c50e4808 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionArgSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionArgSuite.scala @@ -238,6 +238,65 @@ class CompletionArgSuite extends BaseCompletionSuite: "" ) + @Test def `using` = + checkEdit( + s"""|def hello(using String): Unit = ??? + |@main def main1(): Unit = + | val str = "hello" + | hello(st@@) + |""".stripMargin, + s"""|def hello(using String): Unit = ??? + |@main def main1(): Unit = + | val str = "hello" + | hello(using str) + |""".stripMargin, + assertSingleItem = false) + + @Test def `using2` = + checkEdit( + s"""|def hello(using String): Unit = ??? + |@main def main1(): Unit = + | val str = "hello" + | hello(using st@@) + |""".stripMargin, + s"""|def hello(using String): Unit = ??? + |@main def main1(): Unit = + | val str = "hello" + | hello(using str) + |""".stripMargin, + assertSingleItem = false) + + @Test def `using3` = + checkEdit( + s"""|def hello(using String, Int): Unit = ??? + |@main def main1(): Unit = + | val str = "hello" + | val int = 4 + | hello(str, in@@) + |""".stripMargin, + s"""|def hello(using String, Int): Unit = ??? + |@main def main1(): Unit = + | val str = "hello" + | val int = 4 + | hello(using str, int) + |""".stripMargin, + assertSingleItem = false) + + @Test def `using4` = + checkEdit( + s"""|def hello(name: String)(using String): Unit = ??? + |@main def main1(): Unit = + | val str = "hello" + | hello("name")(str@@) + |""".stripMargin, + s"""|def hello(name: String)(using String): Unit = ??? + |@main def main1(): Unit = + | val str = "hello" + | hello("name")(using str) + |""".stripMargin, + assertSingleItem = false + ) + @Test def `default-args` = check( s"""|object Main { From 88eab4cfc3c51220716def01f1f9e489f678fb97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Fa=C5=82drowicz?= Date: Thu, 14 Aug 2025 12:03:50 +0200 Subject: [PATCH 2/2] adjustments after CR --- .../src/main/dotty/tools/pc/completions/Completions.scala | 5 +++-- .../dotty/tools/pc/tests/completion/CompletionArgSuite.scala | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala index 5d816c96706e..78130e7d9fd5 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala @@ -202,9 +202,10 @@ class Completions( } .chain{ suffix => adjustedPath match - case (ident: Ident) :: (app@Apply(_,args)) :: _ if args.size == 1 => + case (ident: Ident) :: (app@Apply(_, List(arg))) :: _ => app.symbol.info match - case mt@MethodType(termNames) if app.symbol.paramSymss.last.exists(_.is(Given)) => + case mt@MethodType(termNames) if app.symbol.paramSymss.last.exists(_.is(Given)) && + !text.substring(app.fun.span.start, arg.span.end).contains("using") => suffix.withNewPrefix(Affix(PrefixKind.Using)) case _ => suffix case _ => suffix diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionArgSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionArgSuite.scala index 1420c50e4808..910044485896 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionArgSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionArgSuite.scala @@ -278,7 +278,7 @@ class CompletionArgSuite extends BaseCompletionSuite: |@main def main1(): Unit = | val str = "hello" | val int = 4 - | hello(using str, int) + | hello(str, int) |""".stripMargin, assertSingleItem = false)