From bfae5dda9822b131b60b4c56f598c4663dc9d641 Mon Sep 17 00:00:00 2001 From: rochala Date: Wed, 21 May 2025 12:35:28 +0200 Subject: [PATCH 1/2] Fix extension member completions on packages --- compiler/src/dotty/tools/dotc/interactive/Completion.scala | 7 +++---- .../dotty/tools/pc/tests/completion/CompletionSuite.scala | 7 +++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/interactive/Completion.scala b/compiler/src/dotty/tools/dotc/interactive/Completion.scala index 36f6fa18e94b..42cc4fc4ad83 100644 --- a/compiler/src/dotty/tools/dotc/interactive/Completion.scala +++ b/compiler/src/dotty/tools/dotc/interactive/Completion.scala @@ -370,7 +370,7 @@ object Completion: * For the results of all `xyzCompletions` methods term names and type names are always treated as different keys in the same map * and they never conflict with each other. */ - class Completer(val mode: Mode, pos: SourcePosition, untpdPath: List[untpd.Tree], matches: Name => Boolean): + class Completer(val mode: Mode, pos: SourcePosition, untpdPath: List[untpd.Tree], matches: Name => Boolean)(using Context): /** Completions for terms and types that are currently in scope: * the members of the current class, local definitions and the symbols that have been imported, * recursively adding completions from outer scopes. @@ -384,7 +384,7 @@ object Completion: * (even if the import follows it syntactically) * - a more deeply nested import shadowing a member or a local definition causes an ambiguity */ - def scopeCompletions(using context: Context): CompletionResult = + lazy val scopeCompletions: CompletionResult = /** Temporary data structure representing denotations with the same name introduced in a given scope * as a member of a type, by a local definition or by an import clause @@ -619,8 +619,7 @@ object Completion: // There are four possible ways for an extension method to be applicable // 1. The extension method is visible under a simple name, by being defined or inherited or imported in a scope enclosing the reference. - val termCompleter = new Completer(Mode.Term, pos, untpdPath, matches) - val extMethodsInScope = termCompleter.scopeCompletions.names.toList.flatMap: + val extMethodsInScope = scopeCompletions.names.toList.flatMap: case (name, denots) => denots.collect: case d: SymDenotation if d.isTerm && d.termRef.symbol.is(Extension) => (d.termRef, name.asTermName) diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala index a48b0b34b320..233193b92907 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala @@ -2250,3 +2250,10 @@ class CompletionSuite extends BaseCompletionSuite: |""".stripMargin, "" ) + + @Test def `no-completions-on-package-selection` = + check( + """package one.@@ + |""".stripMargin, + "" + ) From ee37bea3e9645685d2a3ed2a6e9ed104031be00f Mon Sep 17 00:00:00 2001 From: rochala Date: Wed, 21 May 2025 13:14:20 +0200 Subject: [PATCH 2/2] No completions on package symbols --- .../tools/dotc/interactive/Completion.scala | 25 ++++++++----------- .../pc/tests/completion/CompletionSuite.scala | 18 +++++++++++++ 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/interactive/Completion.scala b/compiler/src/dotty/tools/dotc/interactive/Completion.scala index 42cc4fc4ad83..b2dab9606a9d 100644 --- a/compiler/src/dotty/tools/dotc/interactive/Completion.scala +++ b/compiler/src/dotty/tools/dotc/interactive/Completion.scala @@ -245,9 +245,7 @@ object Completion: case tpd.Select(qual @ tpd.This(_), _) :: _ if qual.span.isSynthetic => completer.scopeCompletions.names case StringContextApplication(qual) => completer.scopeCompletions.names ++ completer.selectionCompletions(qual) - case tpd.Select(qual, _) :: _ if qual.typeOpt.hasSimpleKind => - completer.selectionCompletions(qual) - case tpd.Select(qual, _) :: _ => Map.empty + case tpd.Select(qual, _) :: _ => completer.selectionCompletions(qual) case (tree: tpd.ImportOrExport) :: _ => completer.directMemberCompletions(tree.expr) case _ => completer.scopeCompletions.names @@ -478,17 +476,16 @@ object Completion: def selectionCompletions(qual: tpd.Tree)(using Context): CompletionMap = val adjustedQual = widenQualifier(qual) - val implicitConversionMembers = implicitConversionMemberCompletions(adjustedQual) - val extensionMembers = extensionCompletions(adjustedQual) - val directMembers = directMemberCompletions(adjustedQual) - val namedTupleMembers = namedTupleCompletions(adjustedQual) - - List( - implicitConversionMembers, - extensionMembers, - directMembers, - namedTupleMembers - ).reduce(_ ++ _) + if qual.symbol.is(Package) then + directMemberCompletions(adjustedQual) + else if qual.typeOpt.hasSimpleKind then + implicitConversionMemberCompletions(adjustedQual) ++ + extensionCompletions(adjustedQual) ++ + directMemberCompletions(adjustedQual) ++ + namedTupleCompletions(adjustedQual) + else + Map.empty + /** Completions for members of `qual`'s type. * These include inherited definitions but not members added by extensions or implicit conversions diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala index 233193b92907..9364c00fa855 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala @@ -2257,3 +2257,21 @@ class CompletionSuite extends BaseCompletionSuite: |""".stripMargin, "" ) + + @Test def `no-extension-completion-on-packages` = + check( + """object M: + | scala.runt@@ + |""".stripMargin, + """runtime scala + |PartialFunction scala""".stripMargin // those are the actual members of scala + ) + + @Test def `no-extension-completions-on-package-objects` = + check( + """package object magic { def test: Int = ??? } + |object M: + | magic.@@ + |""".stripMargin, + "test: Int" + )