summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/interactive/scala/tools/nsc/interactive/CompilerControl.scala8
-rw-r--r--src/interactive/scala/tools/nsc/interactive/Global.scala11
-rw-r--r--src/repl/scala/tools/nsc/interpreter/PresentationCompilerCompleter.scala15
-rw-r--r--test/junit/scala/tools/nsc/interpreter/CompletionTest.scala3
4 files changed, 24 insertions, 13 deletions
diff --git a/src/interactive/scala/tools/nsc/interactive/CompilerControl.scala b/src/interactive/scala/tools/nsc/interactive/CompilerControl.scala
index fc6403afa3..586f011429 100644
--- a/src/interactive/scala/tools/nsc/interactive/CompilerControl.scala
+++ b/src/interactive/scala/tools/nsc/interactive/CompilerControl.scala
@@ -268,6 +268,7 @@ trait CompilerControl { self: Global =>
/** Info given for every member found by completion
*/
abstract class Member {
+ def prefix: Type
val sym: Symbol
val tpe: Type
val accessible: Boolean
@@ -289,6 +290,8 @@ trait CompilerControl { self: Global =>
accessible: Boolean,
inherited: Boolean,
viaView: Symbol) extends Member {
+ // should be a case class parameter, but added as a var instead to preserve compatibility with the IDE
+ var prefix: Type = NoType
override def implicitlyAdded = viaView != NoSymbol
}
@@ -296,7 +299,10 @@ trait CompilerControl { self: Global =>
sym: Symbol,
tpe: Type,
accessible: Boolean,
- viaImport: Tree) extends Member
+ viaImport: Tree) extends Member {
+ // should be a case class parameter, but added as a var instead to preserve compatibility with the IDE
+ var prefix: Type = NoType
+ }
// items that get sent to scheduler
diff --git a/src/interactive/scala/tools/nsc/interactive/Global.scala b/src/interactive/scala/tools/nsc/interactive/Global.scala
index d5caf28991..b9d06b3633 100644
--- a/src/interactive/scala/tools/nsc/interactive/Global.scala
+++ b/src/interactive/scala/tools/nsc/interactive/Global.scala
@@ -1031,10 +1031,12 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
def addScopeMember(sym: Symbol, pre: Type, viaImport: Tree) =
locals.add(sym, pre, implicitlyAdded = false) { (s, st) =>
// imported val and var are always marked as inaccessible, but they could be accessed through their getters. SI-7995
- if (s.hasGetter)
+ val member = if (s.hasGetter)
new ScopeMember(s, st, context.isAccessible(s.getter, pre, superAccess = false), viaImport)
else
new ScopeMember(s, st, context.isAccessible(s, pre, superAccess = false), viaImport)
+ member.prefix = pre
+ member
}
def localsToEnclosing() = {
enclosing.addNonShadowed(locals)
@@ -1101,10 +1103,13 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
def addTypeMember(sym: Symbol, pre: Type, inherited: Boolean, viaView: Symbol) = {
val implicitlyAdded = viaView != NoSymbol
members.add(sym, pre, implicitlyAdded) { (s, st) =>
- new TypeMember(s, st,
+ val result = new TypeMember(s, st,
context.isAccessible(if (s.hasGetter) s.getter(s.owner) else s, pre, superAccess && !implicitlyAdded),
inherited,
viaView)
+ result.prefix = pre
+ result
+
}
}
@@ -1157,7 +1162,6 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
def matchingResults(matcher: (M, Name) => Boolean = CompletionResult.prefixMatcher): List[M] = {
results filter (r => matcher(r, name))
}
- def qualifierType: Type = NoType
}
object CompletionResult {
final case class ScopeMembers(positionDelta: Int, results: List[ScopeMember], name: Name) extends CompletionResult {
@@ -1165,7 +1169,6 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
}
final case class TypeMembers(positionDelta: Int, qualifier: Tree, tree: Tree, results: List[TypeMember], name: Name) extends CompletionResult {
type M = TypeMember
- override def qualifierType: Type = qualifier.tpe
}
case object NoResults extends CompletionResult {
override def results = Nil
diff --git a/src/repl/scala/tools/nsc/interpreter/PresentationCompilerCompleter.scala b/src/repl/scala/tools/nsc/interpreter/PresentationCompilerCompleter.scala
index ee901db1a0..3fb4428e76 100644
--- a/src/repl/scala/tools/nsc/interpreter/PresentationCompilerCompleter.scala
+++ b/src/repl/scala/tools/nsc/interpreter/PresentationCompilerCompleter.scala
@@ -54,28 +54,27 @@ class PresentationCompilerCompleter(intp: IMain) extends Completion with ScalaCo
Candidates(cursor, "" :: tpString :: Nil)
}
def candidates(result: Result): Candidates = {
- import result.compiler.CompletionResult._, result.compiler.{Symbol, NoSymbol, Type, Member, NoType, Name}
- def defStringCandidates(qualTpe: Type, matching: List[Member], name: Name): Candidates = {
+ import result.compiler._
+ import CompletionResult._
+ def defStringCandidates(matching: List[Member], name: Name): Candidates = {
val defStrings = for {
member <- matching
if member.symNameDropLocal == name
sym <- member.sym.alternatives
sugared = sym.sugaredSymbolOrSelf
} yield {
- val tp = qualTpe match {
- case NoType => member.tpe
- case _ => qualTpe memberType sym
- }
+ val tp = member.prefix memberType sym
sugared.defStringSeenAs(tp)
}
Candidates(cursor, "" :: defStrings.distinct)
}
val found = result.completionsAt(cursor) match {
case NoResults => Completion.NoCandidates
- case r => val matching = r.matchingResults()
+ case r =>
+ val matching = r.matchingResults()
val tabAfterCommonPrefixCompletion = lastCommonPrefixCompletion.contains(buf.substring(0, cursor)) && matching.exists(_.symNameDropLocal == r.name)
val doubleTab = tabCount > 0 && matching.forall(_.symNameDropLocal == r.name)
- if (tabAfterCommonPrefixCompletion || doubleTab) defStringCandidates(r.qualifierType, matching, r.name)
+ if (tabAfterCommonPrefixCompletion || doubleTab) defStringCandidates(matching, r.name)
else {
if (matching.nonEmpty && matching.forall(_.symNameDropLocal == r.name))
Completion.NoCandidates // don't offer completion if the only option has been fully typed already
diff --git a/test/junit/scala/tools/nsc/interpreter/CompletionTest.scala b/test/junit/scala/tools/nsc/interpreter/CompletionTest.scala
index 70cb2882ba..8c72ed7b32 100644
--- a/test/junit/scala/tools/nsc/interpreter/CompletionTest.scala
+++ b/test/junit/scala/tools/nsc/interpreter/CompletionTest.scala
@@ -94,6 +94,9 @@ class CompletionTest {
// and performs as-seen-from with respect to the prefix
checkExact(completer, "trait T[A]{ lazy val x_y_z: A }; class C extends T[Int] { x_y_z")()
checkExact(completer, "trait T[A]{ lazy val x_y_z: A }; class C extends T[Int] { x_y_z")(EmptyString, "lazy val x_y_z: Int")
+
+ checkExact(completer, "trait T[A] { def foo: A }; (t: T[Int]) => t.foo")()
+ checkExact(completer, "trait T[A] { def foo: A }; (t: T[Int]) => t.foo")(EmptyString, "def foo: Int")
}
@Test