Add an Atom Suggestion for a Module (#1659)

Add an atom suggestion representing a module
This commit is contained in:
Dmitry Bushev 2021-04-13 16:43:36 +03:00 committed by GitHub
parent fde4f2d0d6
commit f43655a80c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 256 additions and 27 deletions

View File

@ -18,6 +18,7 @@ import org.enso.languageserver.refactoring.ProjectNameChangedEvent
import org.enso.languageserver.search.SearchProtocol.SuggestionDatabaseEntry
import org.enso.languageserver.session.JsonSession
import org.enso.languageserver.session.SessionRouter.DeliverToJsonController
import org.enso.polyglot.Suggestion
import org.enso.polyglot.data.{Tree, TypeGraph}
import org.enso.polyglot.runtime.Runtime.Api
import org.enso.searcher.sql.{SqlDatabase, SqlSuggestionsRepo, SqlVersionsRepo}
@ -336,6 +337,72 @@ class SuggestionsHandlerSpec
)
}
"apply update with an atom named as module" taggedAs Retry in withDb {
(_, _, router, _, handler) =>
val clientId = UUID.randomUUID()
// acquire capability
handler ! AcquireCapability(
newJsonSession(clientId),
CapabilityRegistration(ReceivesSuggestionsDatabaseUpdates())
)
expectMsg(CapabilityAcquired)
val moduleName = "Test.Foo"
val moduleAtom = Suggestion.Atom(
externalId = None,
module = moduleName,
name = "Foo",
arguments = Vector(),
returnType = moduleName,
documentation = None
)
val fooAtom = moduleAtom.copy(returnType = "Test.Foo.Foo")
val tree = Tree.Root(
Vector(
Tree.Node(
Api.SuggestionUpdate(
moduleAtom,
Api.SuggestionAction.Add()
),
Vector()
),
Tree.Node(
Api.SuggestionUpdate(
fooAtom,
Api.SuggestionAction.Add()
),
Vector()
)
)
)
// add tree
handler ! Api.SuggestionsDatabaseModuleUpdateNotification(
new File("/tmp/foo"),
contentsVersion(""),
Vector(),
tree
)
val updates = tree.toVector.zipWithIndex.map { case (update, ix) =>
SearchProtocol.SuggestionsDatabaseUpdate.Add(
ix + 1L,
update.suggestion
)
}
router.expectMsg(
DeliverToJsonController(
clientId,
SearchProtocol.SuggestionsDatabaseUpdateNotification(
updates.size.toLong,
updates
)
)
)
}
"apply runtime actions" taggedAs Retry in withDb {
(_, repo, router, _, handler) =>
val clientId = UUID.randomUUID()

View File

@ -124,8 +124,11 @@ final class SuggestionBuilder[A: IndexedSource](val source: A) {
}
}
val builder: TreeBuilder = Vector.newBuilder
builder += Tree.Node(buildModuleAtom(module), Vector())
Tree.Root(
go(Vector.newBuilder, Scope(ir.children, ir.location))
go(builder, Scope(ir.children, ir.location))
)
}
@ -197,6 +200,17 @@ final class SuggestionBuilder[A: IndexedSource](val source: A) {
)
}
/** Build an atom suggestion representing a module. */
private def buildModuleAtom(module: QualifiedName): Suggestion =
Suggestion.Atom(
externalId = None,
module = module.toString,
name = module.item,
arguments = Seq(),
returnType = module.toString,
documentation = None
)
/** Build suggestions for an atom definition. */
private def buildAtom(
bindings: Option[BindingAnalysis.Metadata],

View File

@ -19,6 +19,19 @@ class SuggestionBuilderTest extends CompilerTest {
implicit val passManager: PassManager = new Passes().passManager
private val Module = QualifiedName(List("Unnamed"), "Test")
private val ModuleAtomNode = Tree.Node(
Suggestion.Atom(
externalId = None,
module = Module.toString,
name = Module.item,
arguments = Seq(),
returnType = Module.toString,
documentation = None
),
Vector()
)
"SuggestionBuilder" should {
"build method without explicit arguments" in {
@ -29,6 +42,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Method(
externalId = None,
@ -57,6 +71,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Method(
externalId = None,
@ -86,6 +101,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Method(
externalId = None,
@ -117,6 +133,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Method(
externalId = None,
@ -124,8 +141,10 @@ class SuggestionBuilderTest extends CompilerTest {
name = "foo",
arguments = Seq(
Suggestion.Argument("this", "Unnamed.Test", false, false, None),
Suggestion.Argument("a", SuggestionBuilder.Any, false, false, None),
Suggestion.Argument("b", SuggestionBuilder.Any, false, false, None)
Suggestion
.Argument("a", SuggestionBuilder.Any, false, false, None),
Suggestion
.Argument("b", SuggestionBuilder.Any, false, false, None)
),
selfType = "Unnamed.Test",
returnType = SuggestionBuilder.Any,
@ -168,6 +187,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Method(
externalId = None,
@ -175,7 +195,8 @@ class SuggestionBuilderTest extends CompilerTest {
name = "foo",
arguments = Seq(
Suggestion.Argument("this", "Unnamed.Test", false, false, None),
Suggestion.Argument("a", SuggestionBuilder.Any, false, true, Some("0"))
Suggestion
.Argument("a", SuggestionBuilder.Any, false, true, Some("0"))
),
selfType = "Unnamed.Test",
returnType = SuggestionBuilder.Any,
@ -199,6 +220,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Atom(
externalId = None,
@ -218,8 +240,10 @@ class SuggestionBuilderTest extends CompilerTest {
arguments = Seq(
Suggestion
.Argument("this", "Unnamed.Test.MyType", false, false, None),
Suggestion.Argument("a", SuggestionBuilder.Any, false, false, None),
Suggestion.Argument("b", SuggestionBuilder.Any, false, false, None)
Suggestion
.Argument("a", SuggestionBuilder.Any, false, false, None),
Suggestion
.Argument("b", SuggestionBuilder.Any, false, false, None)
),
selfType = "Unnamed.Test.MyType",
returnType = SuggestionBuilder.Any,
@ -238,7 +262,7 @@ class SuggestionBuilderTest extends CompilerTest {
"""MyAtom.bar a b = a + b"""
val module = code.preprocessModule
build(code, module) shouldEqual Tree.Root(Vector())
build(code, module) shouldEqual Tree.Root(Vector(ModuleAtomNode))
}
"build method with associated type signature" in {
@ -255,6 +279,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Atom(
externalId = None,
@ -300,6 +325,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Atom(
externalId = None,
@ -340,6 +366,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Method(
externalId = None,
@ -347,7 +374,8 @@ class SuggestionBuilderTest extends CompilerTest {
name = "foo",
arguments = Seq(
Suggestion.Argument("this", "Unnamed.Test", false, false, None),
Suggestion.Argument("a", SuggestionBuilder.Any, true, false, None)
Suggestion
.Argument("a", SuggestionBuilder.Any, true, false, None)
),
selfType = "Unnamed.Test",
returnType = SuggestionBuilder.Any,
@ -371,6 +399,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Atom(
externalId = None,
@ -412,6 +441,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Method(
externalId = None,
@ -431,7 +461,8 @@ class SuggestionBuilderTest extends CompilerTest {
module = "Unnamed.Test",
name = "foo",
arguments = Seq(
Suggestion.Argument("a", SuggestionBuilder.Any, false, false, None)
Suggestion
.Argument("a", SuggestionBuilder.Any, false, false, None)
),
returnType = SuggestionBuilder.Any,
scope = Suggestion.Scope(
@ -460,6 +491,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Method(
externalId = None,
@ -479,7 +511,8 @@ class SuggestionBuilderTest extends CompilerTest {
module = "Unnamed.Test",
name = "foo",
arguments = Seq(
Suggestion.Argument("a", SuggestionBuilder.Any, false, false, None)
Suggestion
.Argument("a", SuggestionBuilder.Any, false, false, None)
),
returnType = SuggestionBuilder.Any,
scope = Suggestion.Scope(
@ -521,6 +554,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Method(
externalId = None,
@ -570,6 +604,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Atom(
externalId = None,
@ -628,6 +663,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Method(
externalId = None,
@ -673,6 +709,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Method(
externalId = None,
@ -731,6 +768,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Method(
externalId = None,
@ -777,6 +815,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Atom(
externalId = None,
@ -828,14 +867,17 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Atom(
externalId = None,
module = "Unnamed.Test",
name = "MyType",
arguments = Seq(
Suggestion.Argument("a", SuggestionBuilder.Any, false, false, None),
Suggestion.Argument("b", SuggestionBuilder.Any, false, false, None)
Suggestion
.Argument("a", SuggestionBuilder.Any, false, false, None),
Suggestion
.Argument("b", SuggestionBuilder.Any, false, false, None)
),
returnType = "Unnamed.Test.MyType",
documentation = None
@ -886,14 +928,17 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Atom(
externalId = None,
module = "Unnamed.Test",
name = "MyType",
arguments = Seq(
Suggestion.Argument("a", SuggestionBuilder.Any, false, false, None),
Suggestion.Argument("b", SuggestionBuilder.Any, false, false, None)
Suggestion
.Argument("a", SuggestionBuilder.Any, false, false, None),
Suggestion
.Argument("b", SuggestionBuilder.Any, false, false, None)
),
returnType = "Unnamed.Test.MyType",
documentation = Some(" My sweet type")
@ -945,6 +990,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Atom(
externalId = None,
@ -961,8 +1007,10 @@ class SuggestionBuilderTest extends CompilerTest {
externalId = None,
module = "Unnamed.Test",
name = "Just",
arguments =
Seq(Suggestion.Argument("a", SuggestionBuilder.Any, false, false, None)),
arguments = Seq(
Suggestion
.Argument("a", SuggestionBuilder.Any, false, false, None)
),
returnType = "Unnamed.Test.Just",
documentation = None
),
@ -1001,6 +1049,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Atom(
externalId = None,
@ -1018,7 +1067,8 @@ class SuggestionBuilderTest extends CompilerTest {
module = "Unnamed.Test",
name = "Just",
arguments = Seq(
Suggestion.Argument("a", SuggestionBuilder.Any, false, false, None)
Suggestion
.Argument("a", SuggestionBuilder.Any, false, false, None)
),
returnType = "Unnamed.Test.Just",
documentation = Some(" Something there")
@ -1061,6 +1111,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Atom(
externalId = None,
@ -1131,6 +1182,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Atom(
externalId = None,
@ -1148,7 +1200,8 @@ class SuggestionBuilderTest extends CompilerTest {
module = "Unnamed.Test",
name = "Just",
arguments = Seq(
Suggestion.Argument("a", SuggestionBuilder.Any, false, false, None)
Suggestion
.Argument("a", SuggestionBuilder.Any, false, false, None)
),
returnType = "Unnamed.Test.Just",
documentation = None
@ -1178,7 +1231,8 @@ class SuggestionBuilderTest extends CompilerTest {
arguments = Seq(
Suggestion
.Argument("this", "Unnamed.Test.Nothing", false, false, None),
Suggestion.Argument("f", SuggestionBuilder.Any, false, false, None)
Suggestion
.Argument("f", SuggestionBuilder.Any, false, false, None)
),
selfType = "Unnamed.Test.Nothing",
returnType = SuggestionBuilder.Any,
@ -1194,7 +1248,8 @@ class SuggestionBuilderTest extends CompilerTest {
arguments = Seq(
Suggestion
.Argument("this", "Unnamed.Test.Just", false, false, None),
Suggestion.Argument("f", SuggestionBuilder.Any, false, false, None)
Suggestion
.Argument("f", SuggestionBuilder.Any, false, false, None)
),
selfType = "Unnamed.Test.Just",
returnType = SuggestionBuilder.Any,
@ -1206,7 +1261,7 @@ class SuggestionBuilderTest extends CompilerTest {
)
}
"build module with atom" in {
"build module with simple atom" in {
implicit val moduleContext: ModuleContext = freshModuleContext
val code =
"""type MyType a b
@ -1216,14 +1271,17 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Atom(
externalId = None,
module = "Unnamed.Test",
name = "MyType",
arguments = Seq(
Suggestion.Argument("a", SuggestionBuilder.Any, false, false, None),
Suggestion.Argument("b", SuggestionBuilder.Any, false, false, None)
Suggestion
.Argument("a", SuggestionBuilder.Any, false, false, None),
Suggestion
.Argument("b", SuggestionBuilder.Any, false, false, None)
),
returnType = "Unnamed.Test.MyType",
documentation = None
@ -1278,6 +1336,64 @@ class SuggestionBuilderTest extends CompilerTest {
)
}
"build module with an atom named as module" in {
implicit val moduleContext: ModuleContext = freshModuleContext
val code =
"""type Test a
|
|main = IO.println "Hello!"""".stripMargin
val module = code.preprocessModule
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Atom(
externalId = None,
module = "Unnamed.Test",
name = "Test",
arguments = Seq(
Suggestion
.Argument("a", SuggestionBuilder.Any, false, false, None)
),
returnType = "Unnamed.Test.Test",
documentation = None
),
Vector()
),
Tree.Node(
Suggestion.Method(
externalId = None,
module = "Unnamed.Test",
name = "a",
arguments = List(
Suggestion
.Argument("this", "Unnamed.Test.Test", false, false, None)
),
selfType = "Unnamed.Test.Test",
returnType = SuggestionBuilder.Any,
documentation = None
),
Vector()
),
Tree.Node(
Suggestion.Method(
externalId = None,
module = "Unnamed.Test",
name = "main",
arguments = Seq(
Suggestion.Argument("this", "Unnamed.Test", false, false, None)
),
selfType = "Unnamed.Test",
returnType = SuggestionBuilder.Any,
documentation = None
),
Vector()
)
)
)
}
"build module with overloaded functions" in {
implicit val moduleContext: ModuleContext = freshModuleContext
val code =
@ -1296,6 +1412,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion
.Atom(
@ -1371,6 +1488,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Method(
externalId =
@ -1406,6 +1524,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Method(
externalId = None,
@ -1427,7 +1546,8 @@ class SuggestionBuilderTest extends CompilerTest {
module = "Unnamed.Test",
name = "id",
arguments = Seq(
Suggestion.Argument("x", SuggestionBuilder.Any, false, false, None)
Suggestion
.Argument("x", SuggestionBuilder.Any, false, false, None)
),
returnType = SuggestionBuilder.Any,
scope = Suggestion.Scope(
@ -1459,6 +1579,7 @@ class SuggestionBuilderTest extends CompilerTest {
build(code, module) shouldEqual Tree.Root(
Vector(
ModuleAtomNode,
Tree.Node(
Suggestion.Method(
externalId = None,
@ -1495,8 +1616,6 @@ class SuggestionBuilderTest extends CompilerTest {
}
private val Module = QualifiedName(List("Unnamed"), "Test")
private def build(source: String, ir: IR.Module): Tree.Root[Suggestion] =
SuggestionBuilder(source).build(Module, ir)

View File

@ -88,7 +88,7 @@ class RuntimeSuggestionUpdatesTest
}
def receive: Option[Api.Response] = {
Option(messageQueue.poll(6, TimeUnit.SECONDS))
Option(messageQueue.poll(10, TimeUnit.SECONDS))
}
def receive(n: Int): List[Api.Response] = {
@ -161,6 +161,20 @@ class RuntimeSuggestionUpdatesTest
actions = Vector(Api.SuggestionsDatabaseAction.Clean(moduleName)),
updates = Tree.Root(
Vector(
Tree.Node(
Api.SuggestionUpdate(
Suggestion.Atom(
None,
moduleName,
"Main",
Seq(),
moduleName,
None
),
Api.SuggestionAction.Add()
),
Vector()
),
Tree.Node(
Api.SuggestionUpdate(
Suggestion.Method(
@ -723,6 +737,20 @@ class RuntimeSuggestionUpdatesTest
actions = Vector(Api.SuggestionsDatabaseAction.Clean(moduleName)),
updates = Tree.Root(
Vector(
Tree.Node(
Api.SuggestionUpdate(
Suggestion.Atom(
None,
moduleName,
"Main",
Seq(),
moduleName,
None
),
Api.SuggestionAction.Add()
),
Vector()
),
Tree.Node(
Api.SuggestionUpdate(
Suggestion.Method(

View File

@ -196,6 +196,7 @@ final class SuggestionsTable(tag: Tag)
module,
name,
selfType,
returnType,
scopeStartLine,
scopeStartOffset,
scopeEndLine,