Skip to content

Commit 81804fb

Browse files
Backport "Improve symbol order in completions provided by the presentation compiler" to 3.7.4 (#24048)
Backports #23888 to the 3.7.4. PR submitted by the release tooling. [skip ci]
2 parents 324f6f7 + fba6b35 commit 81804fb

File tree

3 files changed

+71
-11
lines changed

3 files changed

+71
-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.*
@@ -765,6 +766,13 @@ class Completions(
765766
).flatMap(_.alternatives.map(_.symbol)).toSet
766767
)
767768

769+
private lazy val EqualsClass: ClassSymbol = requiredClass("scala.Equals")
770+
private lazy val ArrowAssocClass: ClassSymbol = requiredClass("scala.Predef.ArrowAssoc")
771+
private lazy val EnsuringClass: ClassSymbol = requiredClass("scala.Predef.Ensuring")
772+
private lazy val StringFormatClass: ClassSymbol = requiredClass("scala.Predef.StringFormat")
773+
private lazy val nnMethod: Symbol = defn.ScalaPredefModule.info.member("nn".toTermName).symbol
774+
private lazy val runtimeCheckedMethod: Symbol = defn.ScalaPredefModule.info.member("runtimeChecked".toTermName).symbol
775+
768776
private def isNotLocalForwardReference(sym: Symbol)(using Context): Boolean =
769777
!sym.isLocalToBlock ||
770778
!sym.srcPos.isAfter(completionPos.originalCursorPosition) ||
@@ -783,6 +791,17 @@ class Completions(
783791
(sym.isField && !isJavaClass && !isModuleOrClass) || sym.getter != NoSymbol
784792
catch case _ => false
785793

794+
def isInheritedFromScalaLibrary(sym: Symbol) =
795+
sym.owner == defn.AnyClass ||
796+
sym.owner == defn.ObjectClass ||
797+
sym.owner == defn.ProductClass ||
798+
sym.owner == EqualsClass ||
799+
sym.owner == ArrowAssocClass ||
800+
sym.owner == EnsuringClass ||
801+
sym.owner == StringFormatClass ||
802+
sym == nnMethod ||
803+
sym == runtimeCheckedMethod
804+
786805
def symbolRelevance(sym: Symbol): Int =
787806
var relevance = 0
788807
// symbols defined in this file are more relevant
@@ -800,7 +819,7 @@ class Completions(
800819
case _ =>
801820

802821
// symbols whose owner is a base class are less relevant
803-
if sym.owner == defn.AnyClass || sym.owner == defn.ObjectClass
822+
if isInheritedFromScalaLibrary(sym)
804823
then relevance |= IsInheritedBaseMethod
805824
// symbols not provided via an implicit are more relevant
806825
if sym.is(Implicit) ||
@@ -812,7 +831,7 @@ class Completions(
812831
// accessors of case class members are more relevant
813832
if !sym.is(CaseAccessor) then relevance |= IsNotCaseAccessor
814833
// public symbols are more relevant
815-
if !sym.isPublic then relevance |= IsNotCaseAccessor
834+
if !sym.isPublic then relevance |= IsNotPublic
816835
// synthetic symbols are less relevant (e.g. `copy` on case classes)
817836
if sym.is(Synthetic) && !sym.isAllOf(EnumCase) then
818837
relevance |= IsSynthetic

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,3 +437,44 @@ 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+
|runtimeChecked: `?2`.type
477+
|formatted(fmtstr: String): String
478+
|→[B](y: B): (Bar, B)
479+
| """.stripMargin
480+
)

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,18 +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
120-
|runtimeChecked scala.collection.immutable
121114
|toFactory(from: Any): Factory[Nothing, List[Nothing]]
122-
|formatted(fmtstr: String): String
123-
|→[B](y: B): (List.type, B)
124115
|iterableFactory[A]: Factory[A, List[A]]
125116
|asInstanceOf[X0]: X0
126117
|equals(x$0: Any): Boolean
@@ -129,6 +120,15 @@ class CompletionSuite extends BaseCompletionSuite:
129120
|isInstanceOf[X0]: Boolean
130121
|synchronized[X0](x$0: X0): X0
131122
|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+
|runtimeChecked scala.collection.immutable
130+
|formatted(fmtstr: String): String
131+
|→[B](y: B): (List.type, B)
132132
|""".stripMargin
133133
)
134134

0 commit comments

Comments
 (0)