Skip to content

Commit 034c251

Browse files
authored
Merge pull request #599 from scala/backport-lts-3.3-23888
Backport "Improve symbol order in completions provided by the presentation compiler" to 3.3 LTS
2 parents 207fc97 + f160518 commit 034c251

File tree

3 files changed

+70
-11
lines changed

3 files changed

+70
-11
lines changed

presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import dotty.tools.dotc.ast.untpd
1515
import dotty.tools.dotc.core.Comments.Comment
1616
import dotty.tools.dotc.core.Constants.Constant
1717
import dotty.tools.dotc.core.Contexts.*
18+
import dotty.tools.dotc.core.Decorators.toTermName
1819
import dotty.tools.dotc.core.Denotations.SingleDenotation
1920
import dotty.tools.dotc.core.Flags
2021
import dotty.tools.dotc.core.Flags.*
@@ -768,6 +769,13 @@ class Completions(
768769
).flatMap(_.alternatives.map(_.symbol)).toSet
769770
)
770771

772+
private lazy val EqualsClass: ClassSymbol = requiredClass("scala.Equals")
773+
private lazy val ArrowAssocClass: ClassSymbol = requiredClass("scala.Predef.ArrowAssoc")
774+
private lazy val EnsuringClass: ClassSymbol = requiredClass("scala.Predef.Ensuring")
775+
private lazy val StringFormatClass: ClassSymbol = requiredClass("scala.Predef.StringFormat")
776+
private lazy val nnMethod: Symbol = defn.ScalaPredefModule.info.member("nn".toTermName).symbol
777+
private lazy val runtimeCheckedMethod: Symbol = defn.ScalaPredefModule.info.member("runtimeChecked".toTermName).symbol
778+
771779
private def isNotLocalForwardReference(sym: Symbol)(using Context): Boolean =
772780
!sym.isLocalToBlock ||
773781
!sym.srcPos.isAfter(completionPos.originalCursorPosition) ||
@@ -786,6 +794,17 @@ class Completions(
786794
(sym.isField && !isJavaClass && !isModuleOrClass) || sym.getter != NoSymbol
787795
catch case _ => false
788796

797+
def isInheritedFromScalaLibrary(sym: Symbol) =
798+
sym.owner == defn.AnyClass ||
799+
sym.owner == defn.ObjectClass ||
800+
sym.owner == defn.ProductClass ||
801+
sym.owner == EqualsClass ||
802+
sym.owner == ArrowAssocClass ||
803+
sym.owner == EnsuringClass ||
804+
sym.owner == StringFormatClass ||
805+
sym == nnMethod ||
806+
sym == runtimeCheckedMethod
807+
789808
def symbolRelevance(sym: Symbol): Int =
790809
var relevance = 0
791810
// symbols defined in this file are more relevant
@@ -803,7 +822,7 @@ class Completions(
803822
case _ =>
804823

805824
// symbols whose owner is a base class are less relevant
806-
if sym.owner == defn.AnyClass || sym.owner == defn.ObjectClass
825+
if isInheritedFromScalaLibrary(sym)
807826
then relevance |= IsInheritedBaseMethod
808827
// symbols not provided via an implicit are more relevant
809828
if sym.is(Implicit) ||
@@ -815,7 +834,7 @@ class Completions(
815834
// accessors of case class members are more relevant
816835
if !sym.is(CaseAccessor) then relevance |= IsNotCaseAccessor
817836
// public symbols are more relevant
818-
if !sym.isPublic then relevance |= IsNotCaseAccessor
837+
if !sym.isPublic then relevance |= IsNotPublic
819838
// synthetic symbols are less relevant (e.g. `copy` on case classes)
820839
if sym.is(Synthetic) && !sym.isAllOf(EnumCase) then
821840
relevance |= IsSynthetic

presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionExtensionSuite.scala

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,3 +437,43 @@ class CompletionExtensionSuite extends BaseCompletionSuite:
437437
|""".stripMargin,
438438
assertSingleItem = false
439439
)
440+
441+
@Test def `extension-for-case-class` =
442+
check(
443+
"""|case class Bar():
444+
| def baz(): Unit = ???
445+
|
446+
|object Bar:
447+
| extension (f: Bar)
448+
| def qux: Unit = ???
449+
|
450+
|object Main:
451+
| val _ = Bar().@@
452+
|""".stripMargin,
453+
"""|baz(): Unit
454+
|copy(): Bar
455+
|qux: Unit
456+
|asInstanceOf[X0]: X0
457+
|canEqual(that: Any): Boolean
458+
|equals(x$0: Any): Boolean
459+
|getClass[X0 >: Bar](): Class[? <: X0]
460+
|hashCode(): Int
461+
|isInstanceOf[X0]: Boolean
462+
|productArity: Int
463+
|productElement(n: Int): Any
464+
|productElementName(n: Int): String
465+
|productElementNames: Iterator[String]
466+
|productIterator: Iterator[Any]
467+
|productPrefix: String
468+
|synchronized[X0](x$0: X0): X0
469+
|toString(): String
470+
|->[B](y: B): (Bar, B)
471+
|ensuring(cond: Boolean): Bar
472+
|ensuring(cond: Bar => Boolean): Bar
473+
|ensuring(cond: Boolean, msg: => Any): Bar
474+
|ensuring(cond: Bar => Boolean, msg: => Any): Bar
475+
|nn: `?1`.type
476+
|formatted(fmtstr: String): String
477+
|→[B](y: B): (Bar, B)
478+
| """.stripMargin
479+
)

presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -109,17 +109,9 @@ class CompletionSuite extends BaseCompletionSuite:
109109
|tabulate[A](n: Int)(f: Int => A): List[A]
110110
|unapplySeq[A](x: List[A] @uncheckedVariance): UnapplySeqWrapper[A]
111111
|unfold[A, S](init: S)(f: S => Option[(A, S)]): List[A]
112-
|->[B](y: B): (List.type, B)
113-
|ensuring(cond: Boolean): List.type
114-
|ensuring(cond: List.type => Boolean): List.type
115-
|ensuring(cond: Boolean, msg: => Any): List.type
116-
|ensuring(cond: List.type => Boolean, msg: => Any): List.type
117112
|fromSpecific(from: Any)(it: IterableOnce[Nothing]): List[Nothing]
118113
|fromSpecific(it: IterableOnce[Nothing]): List[Nothing]
119-
|nn: List.type
120114
|toFactory(from: Any): Factory[Nothing, List[Nothing]]
121-
|formatted(fmtstr: String): String
122-
|→[B](y: B): (List.type, B)
123115
|iterableFactory[A]: Factory[A, List[A]]
124116
|asInstanceOf[X0]: X0
125117
|equals(x$0: Any): Boolean
@@ -128,6 +120,14 @@ class CompletionSuite extends BaseCompletionSuite:
128120
|isInstanceOf[X0]: Boolean
129121
|synchronized[X0](x$0: X0): X0
130122
|toString(): String
123+
|->[B](y: B): (List.type, B)
124+
|ensuring(cond: Boolean): List.type
125+
|ensuring(cond: List.type => Boolean): List.type
126+
|ensuring(cond: Boolean, msg: => Any): List.type
127+
|ensuring(cond: List.type => Boolean, msg: => Any): List.type
128+
|nn: List.type
129+
|formatted(fmtstr: String): String
130+
|→[B](y: B): (List.type, B)
131131
|""".stripMargin
132132
)
133133

@@ -2238,7 +2238,7 @@ class CompletionSuite extends BaseCompletionSuite:
22382238
|""".stripMargin,
22392239
"asTerm: Term"
22402240
)
2241-
2241+
22422242
@Test def `derives-no-square-brackets` =
22432243
check(
22442244
"""

0 commit comments

Comments
 (0)