Skip to content

Commit

Permalink
Suggest wilcard import in completions
Browse files Browse the repository at this point in the history
When in import mode, and there's no prefix or the prefix is `_`, and the
qualifier has a stable type, add the wildcard import to the completion
suggestion.
  • Loading branch information
Duhemm committed Nov 23, 2018
1 parent 350dd91 commit 3a9aeb3
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 3 deletions.
4 changes: 4 additions & 0 deletions compiler/src/dotty/tools/dotc/interactive/Completion.scala
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@ object Completion {
// Implicit conversions do not kick in when importing
implicitConversionTargets(qual)(ctx.fresh.setExploreTyperState())
.foreach(addAccessibleMembers)
} else if (qual.tpe.isStable && (prefix.isEmpty || prefix == nme.WILDCARD.toString)) {
// In import mode, suggest the wildcard import if there's no prefix or it is `_`.
val wildcard = ctx.newCompletePackageSymbol(qual.symbol, nme.WILDCARD)

This comment has been minimized.

Copy link
@smarter

smarter Nov 23, 2018

Member

I'd rather not create fake symbols, can we move this check at the end and just add a string to the completion list ?

This comment has been minimized.

Copy link
@allanrenucci

allanrenucci Nov 23, 2018

Contributor

Would need to be special cased in the REPL as well then

This comment has been minimized.

Copy link
@smarter

smarter Nov 23, 2018

Member

ah because we return a List[Symbol], we could use NoSymbol as a hack, or return a List[Symbol | WildcardMarker]

completions.enter(wildcard)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,13 @@ class CompletionTest {
).completion(m1, completionItems => {
val results = CodeCompletion.simplifyResults(completionItems)
val myClass = ("MyClass", Class, "Foo.MyClass")
assertTrue(results.contains(("MyClass", Class, "Foo.MyClass")))
val wildcard = ("_", Module, "_")

// Verify that apart from `MyClass`, we only have the methods that exists on `Foo`
assertTrue((results - myClass).forall { case (_, kind, _) => kind == Method })
assertTrue(results.contains(wildcard))
assertTrue(results.contains(myClass))

// Verify that apart from `MyClass` and `wildcard`, we only have the methods that exists on `Foo`
assertTrue((results -- Set(myClass, wildcard)).forall { case (_, kind, _) => kind == Method })

// Verify that we don't have things coming from an implicit conversion, such as ensuring
assertFalse(results.exists { case (name, _, _) => name == "ensuring" })
Expand Down Expand Up @@ -175,4 +178,24 @@ class CompletionTest {
|}""".withSource
.completion(m1, results => assertTrue(results.nonEmpty))
}

@Test def noWildcardOutsideImport: Unit = {
code"""class Foo { def bar = 0 }
|object Bar {
| val foo = new Foo
| foo.${m1}
|}""".withSource
.completion(m1, results => {
assertFalse("`_` was a completion result", results.exists(_.getLabel == "_"))
assertTrue(results.forall(_.getKind == Method))
})
}

@Test def importCompletionShowWildcard: Unit = {
code"""import java.${m1}""".withSource
.completion(m1, results => {
assertTrue(results.exists(r => r.getLabel == "_"))
assertTrue(results.forall(_.getKind == Module))
})
}
}

0 comments on commit 3a9aeb3

Please sign in to comment.