From 779df52ffbe6204a13eeff5c491b3a6839499edd Mon Sep 17 00:00:00 2001 From: NPCRUS Date: Tue, 1 Apr 2025 13:25:36 +0200 Subject: [PATCH 1/2] initial commit --- .../tools/dotc/interactive/Completion.scala | 14 ++++++++++- .../tools/pc/tests/completion/BlaSuite.scala | 24 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 presentation-compiler/test/dotty/tools/pc/tests/completion/BlaSuite.scala diff --git a/compiler/src/dotty/tools/dotc/interactive/Completion.scala b/compiler/src/dotty/tools/dotc/interactive/Completion.scala index e59a8e0b882d..275884b0b9b6 100644 --- a/compiler/src/dotty/tools/dotc/interactive/Completion.scala +++ b/compiler/src/dotty/tools/dotc/interactive/Completion.scala @@ -97,6 +97,8 @@ object Completion: else if sel.isGiven && sel.bound.span.contains(pos.span) then Mode.ImportOrExport else Mode.None // import scala.{util => u@@} case GenericImportOrExport(_) => Mode.ImportOrExport | Mode.Scope // import TrieMa@@ + case untpd.InterpolatedString(_, untpd.Literal(Constants.Constant(_: String)) :: _) :: _ => + Mode.Term | Mode.Scope case untpd.Literal(Constants.Constant(_: String)) :: _ => Mode.Term | Mode.Scope // literal completions case (ref: untpd.RefTree) :: _ => val maybeSelectMembers = if ref.isInstanceOf[untpd.Select] then Mode.Member else Mode.Scope @@ -221,7 +223,17 @@ object Completion: // Ignore synthetic select from `This` because in code it was `Ident` // See example in dotty.tools.languageserver.CompletionTest.syntheticThis case tpd.Select(qual @ tpd.This(_), _) :: _ if qual.span.isSynthetic => completer.scopeCompletions - case tpd.Select(qual, _) :: _ if qual.typeOpt.hasSimpleKind => completer.selectionCompletions(qual) + case tpd.Select(b @ tpd.Apply(c @ tpd.Select(d @ tpd.Select(_, StdNames.nme.StringContext), _), _), _) :: _ => + Seq(b,c,d).foreach { tree => + println("---------------------------") + println(tree) + println(tree.show) + println(completer.selectionCompletions(tree)) + } + println(completer.scopeCompletions) + completer.scopeCompletions ++ completer.selectionCompletions(b) + case tpd.Select(qual, _) :: _ if qual.typeOpt.hasSimpleKind => + completer.selectionCompletions(qual) case tpd.Select(qual, _) :: _ => Map.empty case (tree: tpd.ImportOrExport) :: _ => completer.directMemberCompletions(tree.expr) case _ => completer.scopeCompletions diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/BlaSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/BlaSuite.scala new file mode 100644 index 000000000000..70c0d0b031c7 --- /dev/null +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/BlaSuite.scala @@ -0,0 +1,24 @@ +package dotty.tools.pc.tests.completion + +import dotty.tools.pc.base.BaseCompletionSuite +import org.junit.Test + +class BlaSuite extends BaseCompletionSuite: + @Test + def t1 = check( + """ + |object M: + | val VersionRegex = "".r + | VersionRe@@"1234" + """.stripMargin, + "|VersionRegex: Regex".stripMargin + ) + + @Test + def t2 = check( + """ + |object M: + | ra@@"1234" + """.stripMargin, + "|raw(args: Any*): String".stripMargin + ) \ No newline at end of file From 1e85b360d2d459204cd6a4748dcacaec76179bca Mon Sep 17 00:00:00 2001 From: NPCRUS Date: Wed, 2 Apr 2025 13:17:06 +0200 Subject: [PATCH 2/2] - checkEdit tests - extractor for StringContext apply - cleanup --- .../tools/dotc/interactive/Completion.scala | 19 ++--- .../tools/pc/tests/completion/BlaSuite.scala | 24 ------ .../CompletionStringContextSuite.scala | 79 +++++++++++++++++++ 3 files changed, 89 insertions(+), 33 deletions(-) delete mode 100644 presentation-compiler/test/dotty/tools/pc/tests/completion/BlaSuite.scala create mode 100644 presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionStringContextSuite.scala diff --git a/compiler/src/dotty/tools/dotc/interactive/Completion.scala b/compiler/src/dotty/tools/dotc/interactive/Completion.scala index 275884b0b9b6..cef5de613920 100644 --- a/compiler/src/dotty/tools/dotc/interactive/Completion.scala +++ b/compiler/src/dotty/tools/dotc/interactive/Completion.scala @@ -173,6 +173,14 @@ object Completion: case (importOrExport: untpd.ImportOrExport) :: _ => Some(importOrExport) case _ => None + private object StringContextApplication: + def unapply(path: List[tpd.Tree]): Option[tpd.Apply] = + path match + case tpd.Select(qual @ tpd.Apply(tpd.Select(tpd.Select(_, StdNames.nme.StringContext), _), _), _) :: _ => + Some(qual) + case _ => None + + /** Inspect `path` to determine the offset where the completion result should be inserted. */ def completionOffset(untpdPath: List[untpd.Tree]): Int = untpdPath match @@ -223,15 +231,8 @@ object Completion: // Ignore synthetic select from `This` because in code it was `Ident` // See example in dotty.tools.languageserver.CompletionTest.syntheticThis case tpd.Select(qual @ tpd.This(_), _) :: _ if qual.span.isSynthetic => completer.scopeCompletions - case tpd.Select(b @ tpd.Apply(c @ tpd.Select(d @ tpd.Select(_, StdNames.nme.StringContext), _), _), _) :: _ => - Seq(b,c,d).foreach { tree => - println("---------------------------") - println(tree) - println(tree.show) - println(completer.selectionCompletions(tree)) - } - println(completer.scopeCompletions) - completer.scopeCompletions ++ completer.selectionCompletions(b) + case StringContextApplication(qual) => + completer.scopeCompletions ++ completer.selectionCompletions(qual) case tpd.Select(qual, _) :: _ if qual.typeOpt.hasSimpleKind => completer.selectionCompletions(qual) case tpd.Select(qual, _) :: _ => Map.empty diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/BlaSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/BlaSuite.scala deleted file mode 100644 index 70c0d0b031c7..000000000000 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/BlaSuite.scala +++ /dev/null @@ -1,24 +0,0 @@ -package dotty.tools.pc.tests.completion - -import dotty.tools.pc.base.BaseCompletionSuite -import org.junit.Test - -class BlaSuite extends BaseCompletionSuite: - @Test - def t1 = check( - """ - |object M: - | val VersionRegex = "".r - | VersionRe@@"1234" - """.stripMargin, - "|VersionRegex: Regex".stripMargin - ) - - @Test - def t2 = check( - """ - |object M: - | ra@@"1234" - """.stripMargin, - "|raw(args: Any*): String".stripMargin - ) \ No newline at end of file diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionStringContextSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionStringContextSuite.scala new file mode 100644 index 000000000000..689be1862bcc --- /dev/null +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionStringContextSuite.scala @@ -0,0 +1,79 @@ +package dotty.tools.pc.tests.completion + +import dotty.tools.pc.base.BaseCompletionSuite +import org.junit.Test +import dotty.tools.dotc.core.Types.ThisType.raw + +class CompletionStringContextSuite extends BaseCompletionSuite: + @Test + def inScopeSymbol = check( + """ + |object M: + | val VersionRegex = "".r + | VersionRe@@"1234" + """.stripMargin, + "|VersionRegex: Regex".stripMargin + ) + + @Test + def workspaceSymbol = check( + """ + |object M: + | ListBuf@@"1234" + """.stripMargin, + """ + |ListBuffer[A](elems: A*): ListBuffer[A] - scala.collection.mutable + |new ListBuffer[A]: ListBuffer[A] - scala.collection.mutable + |ListBuffer - scala.collection.mutable + |""".stripMargin + ) + + @Test + def providedSymbol = check( + """ + |object M: + | ra@@"1234" + """.stripMargin, + "|raw(args: Any*): String".stripMargin + ) + + // bellow are tests of edits + @Test + def editTest1 = checkEdit( + """ + |object M: + | ra@@"1234" + """.stripMargin, + """ + |object M: + | raw"1234" + |""".stripMargin + ) + + @Test + def editTest2 = checkEdit( + """ + |object M: + | printl@@"1234" + """.stripMargin, + """ + |object M: + | println"1234" + |""".stripMargin, + assertSingleItem = false + ) + + @Test + def editTest3 = checkEdit( + """ + |object M: + | def select(s: String): String = s + | selec@@"1234" + """.stripMargin, + """ + |object M: + | def select(s: String): String = s + | select"1234" + |""".stripMargin, + assertSingleItem = false + ) \ No newline at end of file