mirror of
https://github.com/enso-org/enso.git
synced 2024-12-23 13:02:07 +03:00
Add support for conversions in Language Server (#3175)
This commit is contained in:
parent
c4d22102cf
commit
607330712a
@ -140,7 +140,6 @@ transport formats, please look [here](./protocol-architecture).
|
||||
- [`search/suggestionsDatabaseUpdate`](#searchsuggestionsdatabaseupdate)
|
||||
- [`search/suggestionsOrderDatabaseUpdate`](#searchsuggestionsorderdatabaseupdate)
|
||||
- [`search/completion`](#searchcompletion)
|
||||
- [`search/import`](#searchimport)
|
||||
- [Input/Output Operations](#inputoutput-operations)
|
||||
- [`io/redirectStandardOutput`](#ioredirectstandardoutput)
|
||||
- [`io/suppressStandardOutput`](#iosuppressstandardoutput)
|
||||
@ -3882,49 +3881,6 @@ the type match.
|
||||
- [`ModuleNameNotResolvedError`](#modulenamenotresolvederror) the module name
|
||||
cannot be extracted from the provided file path parameter
|
||||
|
||||
### `search/import`
|
||||
|
||||
Sent from client to the server to receive the information required for module
|
||||
import.
|
||||
|
||||
- **Type:** Request
|
||||
- **Direction:** Client -> Server
|
||||
- **Connection:** Protocol
|
||||
- **Visibility:** Public
|
||||
|
||||
#### Parameters
|
||||
|
||||
```typescript
|
||||
{
|
||||
/**
|
||||
* The id of suggestion to import.
|
||||
*/
|
||||
id: SuggestionId;
|
||||
}
|
||||
```
|
||||
|
||||
#### Result
|
||||
|
||||
```typescript
|
||||
{
|
||||
/**
|
||||
* The definition module of the suggestion.
|
||||
*/
|
||||
module: String;
|
||||
|
||||
/**
|
||||
* The name of the resolved suggestion.
|
||||
*/
|
||||
symbol: String;
|
||||
|
||||
/**
|
||||
* The list of modules that re-export the suggestion. Modules are ordered
|
||||
* from the least to most nested.
|
||||
*/
|
||||
exports: Export[];
|
||||
}
|
||||
```
|
||||
|
||||
#### Errors
|
||||
|
||||
- [`SuggestionsDatabaseError`](#suggestionsdatabaseerror) an error accessing the
|
||||
|
@ -471,7 +471,6 @@ class JsonConnectionController(
|
||||
.props(requestTimeout, suggestionsHandler),
|
||||
Completion -> search.CompletionHandler
|
||||
.props(requestTimeout, suggestionsHandler),
|
||||
Import -> search.ImportHandler.props(requestTimeout, suggestionsHandler),
|
||||
ExecuteExpression -> ExecuteExpressionHandler
|
||||
.props(rpcSession.clientId, requestTimeout, contextRegistry),
|
||||
AttachVisualisation -> AttachVisualisationHandler
|
||||
|
@ -68,7 +68,6 @@ object JsonRpc {
|
||||
.registerRequest(GetSuggestionsDatabaseVersion)
|
||||
.registerRequest(InvalidateSuggestionsDatabase)
|
||||
.registerRequest(Completion)
|
||||
.registerRequest(Import)
|
||||
.registerRequest(RenameProject)
|
||||
.registerRequest(ProjectInfo)
|
||||
.registerRequest(EditionsListAvailable)
|
||||
|
@ -1,79 +0,0 @@
|
||||
package org.enso.languageserver.requesthandler.search
|
||||
|
||||
import akka.actor.{Actor, ActorRef, Cancellable, Props, Status}
|
||||
import com.typesafe.scalalogging.LazyLogging
|
||||
import org.enso.jsonrpc._
|
||||
import org.enso.languageserver.requesthandler.RequestTimeout
|
||||
import org.enso.languageserver.search.SearchApi.{
|
||||
Import,
|
||||
SuggestionsDatabaseError
|
||||
}
|
||||
import org.enso.languageserver.search.{SearchFailureMapper, SearchProtocol}
|
||||
import org.enso.languageserver.util.UnhandledLogging
|
||||
|
||||
import scala.concurrent.duration.FiniteDuration
|
||||
|
||||
/** A request handler for `search/import` command.
|
||||
*
|
||||
* @param timeout request timeout
|
||||
* @param suggestionsHandler a reference to the suggestions handler
|
||||
*/
|
||||
class ImportHandler(
|
||||
timeout: FiniteDuration,
|
||||
suggestionsHandler: ActorRef
|
||||
) extends Actor
|
||||
with LazyLogging
|
||||
with UnhandledLogging {
|
||||
|
||||
import context.dispatcher
|
||||
|
||||
override def receive: Receive = requestStage
|
||||
|
||||
private def requestStage: Receive = {
|
||||
case Request(Import, id, Import.Params(suggestionId)) =>
|
||||
suggestionsHandler ! SearchProtocol.Import(suggestionId)
|
||||
val cancellable =
|
||||
context.system.scheduler.scheduleOnce(timeout, self, RequestTimeout)
|
||||
context.become(responseStage(id, sender(), cancellable))
|
||||
}
|
||||
|
||||
private def responseStage(
|
||||
id: Id,
|
||||
replyTo: ActorRef,
|
||||
cancellable: Cancellable
|
||||
): Receive = {
|
||||
case Status.Failure(ex) =>
|
||||
logger.error("Search import error.", ex)
|
||||
replyTo ! ResponseError(Some(id), SuggestionsDatabaseError)
|
||||
cancellable.cancel()
|
||||
context.stop(self)
|
||||
|
||||
case RequestTimeout =>
|
||||
logger.error("Request [{}] timed out.", id)
|
||||
replyTo ! ResponseError(Some(id), Errors.RequestTimeout)
|
||||
context.stop(self)
|
||||
|
||||
case msg: SearchProtocol.SearchFailure =>
|
||||
replyTo ! ResponseError(Some(id), SearchFailureMapper.mapFailure(msg))
|
||||
|
||||
case SearchProtocol.ImportResult(module, symbol, exports) =>
|
||||
replyTo ! ResponseResult(
|
||||
Import,
|
||||
id,
|
||||
Import.Result(module, symbol, exports)
|
||||
)
|
||||
cancellable.cancel()
|
||||
context.stop(self)
|
||||
}
|
||||
}
|
||||
|
||||
object ImportHandler {
|
||||
|
||||
/** Creates configuration object used to create a [[ImportHandler]].
|
||||
*
|
||||
* @param timeout request timeout
|
||||
* @param suggestionsHandler a reference to the suggestions handler
|
||||
*/
|
||||
def props(timeout: FiniteDuration, suggestionsHandler: ActorRef): Props =
|
||||
Props(new ImportHandler(timeout, suggestionsHandler))
|
||||
}
|
@ -3,7 +3,6 @@ package org.enso.languageserver.search
|
||||
import org.enso.jsonrpc.{Error, HasParams, HasResult, Method, Unused}
|
||||
import org.enso.languageserver.filemanager.Path
|
||||
import org.enso.languageserver.search.SearchProtocol.{
|
||||
Export,
|
||||
SuggestionDatabaseEntry,
|
||||
SuggestionId,
|
||||
SuggestionKind,
|
||||
@ -90,20 +89,6 @@ object SearchApi {
|
||||
}
|
||||
}
|
||||
|
||||
case object Import extends Method("search/import") {
|
||||
|
||||
case class Params(id: Long)
|
||||
|
||||
case class Result(module: String, symbol: String, exports: Seq[Export])
|
||||
|
||||
implicit val hasParams = new HasParams[this.type] {
|
||||
type Params = Import.Params
|
||||
}
|
||||
implicit val hasResult = new HasResult[this.type] {
|
||||
type Result = Import.Result
|
||||
}
|
||||
}
|
||||
|
||||
case object SuggestionsDatabaseError
|
||||
extends Error(7001, "Suggestions database error")
|
||||
|
||||
|
@ -60,6 +60,14 @@ object SearchProtocol {
|
||||
)
|
||||
.dropNullValues
|
||||
|
||||
case conversion: Suggestion.Conversion =>
|
||||
Encoder[Suggestion.Method]
|
||||
.apply(conversionToMethod(conversion))
|
||||
.deepMerge(
|
||||
Json.obj(CodecField.Type -> SuggestionType.Method.asJson)
|
||||
)
|
||||
.dropNullValues
|
||||
|
||||
case function: Suggestion.Function =>
|
||||
Encoder[Suggestion.Function]
|
||||
.apply(function)
|
||||
@ -75,6 +83,29 @@ object SearchProtocol {
|
||||
.dropNullValues
|
||||
}
|
||||
|
||||
private def conversionToMethod(
|
||||
conversion: Suggestion.Conversion
|
||||
): Suggestion.Method = {
|
||||
val arg = Suggestion.Argument(
|
||||
Suggestion.Kind.Conversion.From,
|
||||
conversion.sourceType,
|
||||
false,
|
||||
false,
|
||||
None
|
||||
)
|
||||
Suggestion.Method(
|
||||
conversion.externalId,
|
||||
conversion.module,
|
||||
Suggestion.Kind.Conversion.From,
|
||||
arg +: conversion.arguments,
|
||||
conversion.returnType,
|
||||
conversion.returnType,
|
||||
conversion.documentation,
|
||||
conversion.documentationHtml,
|
||||
conversion.reexport
|
||||
)
|
||||
}
|
||||
|
||||
implicit val suggestionDecoder: Decoder[Suggestion] =
|
||||
Decoder.instance { cursor =>
|
||||
cursor.downField(CodecField.Type).as[String].flatMap {
|
||||
@ -280,6 +311,9 @@ object SearchProtocol {
|
||||
/** A method suggestion. */
|
||||
case object Method extends SuggestionKind
|
||||
|
||||
/** A conversion suggestion. */
|
||||
case object Conversion extends SuggestionKind
|
||||
|
||||
/** A function suggestion. */
|
||||
case object Function extends SuggestionKind
|
||||
|
||||
@ -295,11 +329,12 @@ object SearchProtocol {
|
||||
*/
|
||||
def apply(kind: Suggestion.Kind): SuggestionKind =
|
||||
kind match {
|
||||
case Suggestion.Kind.Module => Module
|
||||
case Suggestion.Kind.Atom => Atom
|
||||
case Suggestion.Kind.Method => Method
|
||||
case Suggestion.Kind.Function => Function
|
||||
case Suggestion.Kind.Local => Local
|
||||
case Suggestion.Kind.Module => Module
|
||||
case Suggestion.Kind.Atom => Atom
|
||||
case Suggestion.Kind.Method => Method
|
||||
case Suggestion.Kind.Conversion => Conversion
|
||||
case Suggestion.Kind.Function => Function
|
||||
case Suggestion.Kind.Local => Local
|
||||
}
|
||||
|
||||
/** Convert from API kind to [[Suggestion.Kind]]
|
||||
@ -309,11 +344,12 @@ object SearchProtocol {
|
||||
*/
|
||||
def toSuggestion(kind: SuggestionKind): Suggestion.Kind =
|
||||
kind match {
|
||||
case Module => Suggestion.Kind.Module
|
||||
case Atom => Suggestion.Kind.Atom
|
||||
case Method => Suggestion.Kind.Method
|
||||
case Function => Suggestion.Kind.Function
|
||||
case Local => Suggestion.Kind.Local
|
||||
case Module => Suggestion.Kind.Module
|
||||
case Atom => Suggestion.Kind.Atom
|
||||
case Method => Suggestion.Kind.Method
|
||||
case Conversion => Suggestion.Kind.Conversion
|
||||
case Function => Suggestion.Kind.Function
|
||||
case Local => Suggestion.Kind.Local
|
||||
}
|
||||
}
|
||||
|
||||
@ -413,18 +449,6 @@ object SearchProtocol {
|
||||
*/
|
||||
case class CompletionResult(currentVersion: Long, results: Seq[SuggestionId])
|
||||
|
||||
/** The request returning the info about the suggestion import.
|
||||
*
|
||||
* @param id the requested suggestion id
|
||||
*/
|
||||
case class Import(id: SuggestionId)
|
||||
|
||||
/** The request returning the info about the suggestion import.
|
||||
*
|
||||
* @param suggestion the requested suggestion
|
||||
*/
|
||||
case class ImportSuggestion(suggestion: Suggestion)
|
||||
|
||||
/** Base trait for export statements. */
|
||||
sealed trait Export {
|
||||
def module: String
|
||||
|
@ -27,10 +27,7 @@ import org.enso.languageserver.filemanager.{
|
||||
import org.enso.languageserver.refactoring.ProjectNameChangedEvent
|
||||
import org.enso.languageserver.runtime.RuntimeFailureMapper
|
||||
import org.enso.languageserver.search.SearchProtocol._
|
||||
import org.enso.languageserver.search.handler.{
|
||||
ImportModuleHandler,
|
||||
InvalidateModulesIndexHandler
|
||||
}
|
||||
import org.enso.languageserver.search.handler.InvalidateModulesIndexHandler
|
||||
import org.enso.languageserver.session.SessionRouter.DeliverToJsonController
|
||||
import org.enso.languageserver.util.UnhandledLogging
|
||||
import org.enso.logger.masking.MaskedPath
|
||||
@ -352,23 +349,6 @@ final class SuggestionsHandler(
|
||||
}
|
||||
.pipeTo(sender())
|
||||
|
||||
case Import(suggestionId) =>
|
||||
val action = for {
|
||||
result <- suggestionsRepo.select(suggestionId)
|
||||
} yield result
|
||||
.map(SearchProtocol.ImportSuggestion)
|
||||
.getOrElse(SearchProtocol.SuggestionNotFoundError)
|
||||
|
||||
val runtimeFailureMapper = RuntimeFailureMapper(contentRootManager)
|
||||
val handler = context.system.actorOf(
|
||||
ImportModuleHandler.props(
|
||||
runtimeFailureMapper,
|
||||
timeout,
|
||||
runtimeConnector
|
||||
)
|
||||
)
|
||||
action.pipeTo(handler)(sender())
|
||||
|
||||
case FileDeletedEvent(path) =>
|
||||
getModuleName(projectName, path)
|
||||
.flatMap { either =>
|
||||
|
@ -1,93 +0,0 @@
|
||||
package org.enso.languageserver.search.handler
|
||||
|
||||
import akka.actor.{Actor, ActorRef, Cancellable, Props}
|
||||
import com.typesafe.scalalogging.LazyLogging
|
||||
import org.enso.languageserver.requesthandler.RequestTimeout
|
||||
import org.enso.languageserver.runtime.RuntimeFailureMapper
|
||||
import org.enso.languageserver.search.SearchProtocol
|
||||
import org.enso.languageserver.util.UnhandledLogging
|
||||
import org.enso.polyglot.runtime.Runtime.Api
|
||||
|
||||
import java.util.UUID
|
||||
import scala.concurrent.duration.FiniteDuration
|
||||
|
||||
/** A request handler for import module command.
|
||||
*
|
||||
* @param runtimeFailureMapper mapper for runtime failures
|
||||
* @param timeout request timeout
|
||||
* @param runtime reference to the runtime connector
|
||||
*/
|
||||
final class ImportModuleHandler(
|
||||
runtimeFailureMapper: RuntimeFailureMapper,
|
||||
timeout: FiniteDuration,
|
||||
runtime: ActorRef
|
||||
) extends Actor
|
||||
with LazyLogging
|
||||
with UnhandledLogging {
|
||||
|
||||
import context.dispatcher
|
||||
|
||||
override def receive: Receive = requestStage
|
||||
|
||||
private def requestStage: Receive = {
|
||||
case SearchProtocol.ImportSuggestion(suggestion) =>
|
||||
runtime ! Api.Request(
|
||||
UUID.randomUUID(),
|
||||
Api.ImportSuggestionRequest(suggestion)
|
||||
)
|
||||
val cancellable =
|
||||
context.system.scheduler.scheduleOnce(timeout, self, RequestTimeout)
|
||||
context.become(responseStage(sender(), cancellable))
|
||||
|
||||
case msg: SearchProtocol.SearchFailure =>
|
||||
sender() ! msg
|
||||
context.stop(self)
|
||||
}
|
||||
|
||||
private def responseStage(
|
||||
replyTo: ActorRef,
|
||||
cancellable: Cancellable
|
||||
): Receive = {
|
||||
case RequestTimeout =>
|
||||
replyTo ! RequestTimeout
|
||||
context.stop(self)
|
||||
|
||||
case Api.Response(_, Api.ImportSuggestionResponse(module, sym, exports)) =>
|
||||
replyTo ! SearchProtocol.ImportResult(
|
||||
module,
|
||||
sym,
|
||||
exports.map(toSearchExport)
|
||||
)
|
||||
cancellable.cancel()
|
||||
context.stop(self)
|
||||
|
||||
case Api.Response(_, error: Api.Error) =>
|
||||
replyTo ! runtimeFailureMapper.mapApiError(error)
|
||||
cancellable.cancel()
|
||||
context.stop(self)
|
||||
}
|
||||
|
||||
private def toSearchExport(export: Api.Export): SearchProtocol.Export =
|
||||
export match {
|
||||
case Api.Export.Unqualified(module) =>
|
||||
SearchProtocol.Export.Unqualified(module)
|
||||
case Api.Export.Qualified(module, alias) =>
|
||||
SearchProtocol.Export.Qualified(module, alias)
|
||||
}
|
||||
}
|
||||
|
||||
object ImportModuleHandler {
|
||||
|
||||
/** Creates a configuration object used to create [[ImportModuleHandler]].
|
||||
*
|
||||
* @param runtimeFailureMapper mapper for runtime failures
|
||||
* @param timeout request timeout
|
||||
* @param runtime reference to the runtime conector
|
||||
*/
|
||||
def props(
|
||||
runtimeFailureMapper: RuntimeFailureMapper,
|
||||
timeout: FiniteDuration,
|
||||
runtime: ActorRef
|
||||
): Props =
|
||||
Props(new ImportModuleHandler(runtimeFailureMapper, timeout, runtime))
|
||||
}
|
@ -21,6 +21,10 @@ import org.enso.logger.masking.ToLogString
|
||||
value = classOf[Suggestion.Method],
|
||||
name = "suggestionMethod"
|
||||
),
|
||||
new JsonSubTypes.Type(
|
||||
value = classOf[Suggestion.Conversion],
|
||||
name = "suggestionConversion"
|
||||
),
|
||||
new JsonSubTypes.Type(
|
||||
value = classOf[Suggestion.Function],
|
||||
name = "suggestionFunction"
|
||||
@ -49,11 +53,12 @@ object Suggestion {
|
||||
|
||||
def apply(suggestion: Suggestion): Kind =
|
||||
suggestion match {
|
||||
case _: Module => Module
|
||||
case _: Atom => Atom
|
||||
case _: Method => Method
|
||||
case _: Function => Function
|
||||
case _: Local => Local
|
||||
case _: Module => Module
|
||||
case _: Atom => Atom
|
||||
case _: Method => Method
|
||||
case _: Conversion => Conversion
|
||||
case _: Function => Function
|
||||
case _: Local => Local
|
||||
}
|
||||
|
||||
/** The module suggestion. */
|
||||
@ -65,6 +70,12 @@ object Suggestion {
|
||||
/** The method suggestion. */
|
||||
case object Method extends Kind
|
||||
|
||||
/** The conversion suggestion. */
|
||||
case object Conversion extends Kind {
|
||||
val From = "from"
|
||||
val To = "to"
|
||||
}
|
||||
|
||||
/** The function suggestion. */
|
||||
case object Function extends Kind
|
||||
|
||||
@ -80,6 +91,7 @@ object Suggestion {
|
||||
case _: Module => None
|
||||
case _: Atom => None
|
||||
case method: Method => Some(method.selfType)
|
||||
case _: Conversion => None
|
||||
case _: Function => None
|
||||
case _: Local => None
|
||||
}
|
||||
@ -235,6 +247,46 @@ object Suggestion {
|
||||
s",reexport=$reexport)"
|
||||
}
|
||||
|
||||
/** A conversion function.
|
||||
*
|
||||
* @param externalId the external id
|
||||
* @param module the module name
|
||||
* @param arguments the list of arguments
|
||||
* @param sourceType the source type of a conversion
|
||||
* @param returnType the return type of a conversion
|
||||
* @param documentation the documentation string
|
||||
* @param documentationHtml the documentation rendered as HTML
|
||||
* @param reexport the module re-exporting this conversion
|
||||
*/
|
||||
case class Conversion(
|
||||
externalId: Option[ExternalId],
|
||||
module: String,
|
||||
arguments: Seq[Argument],
|
||||
sourceType: String,
|
||||
returnType: String,
|
||||
documentation: Option[String],
|
||||
documentationHtml: Option[String],
|
||||
reexport: Option[String] = None
|
||||
) extends Suggestion {
|
||||
|
||||
/** @inheritdoc */
|
||||
override def name: String =
|
||||
Kind.Conversion.From
|
||||
|
||||
/** @inheritdoc */
|
||||
override def toLogString(shouldMask: Boolean): String =
|
||||
"Conversion(" +
|
||||
s"module=$module," +
|
||||
s"arguments=${arguments.map(_.toLogString(shouldMask))}," +
|
||||
s"sourceType=$sourceType," +
|
||||
s"returnType=$returnType," +
|
||||
s"documentation=" + (if (shouldMask) documentation.map(_ => STUB)
|
||||
else documentation) +
|
||||
s",documentationHtml=" + (if (shouldMask) documentationHtml.map(_ => STUB)
|
||||
else documentationHtml) +
|
||||
s",reexport=$reexport)"
|
||||
}
|
||||
|
||||
/** A local function definition.
|
||||
*
|
||||
* @param externalId the external id
|
||||
|
@ -198,14 +198,6 @@ object Runtime {
|
||||
value = classOf[Api.VerifyModulesIndexResponse],
|
||||
name = "verifyModulesIndexResponse"
|
||||
),
|
||||
new JsonSubTypes.Type(
|
||||
value = classOf[Api.ImportSuggestionRequest],
|
||||
name = "importSuggestionRequest"
|
||||
),
|
||||
new JsonSubTypes.Type(
|
||||
value = classOf[Api.ImportSuggestionResponse],
|
||||
name = "importSuggestionResponse"
|
||||
),
|
||||
new JsonSubTypes.Type(
|
||||
value = classOf[Api.GetTypeGraphRequest],
|
||||
name = "getTypeGraphRequest"
|
||||
@ -1382,31 +1374,6 @@ object Runtime {
|
||||
final case class VerifyModulesIndexResponse(remove: Seq[String])
|
||||
extends ApiResponse
|
||||
|
||||
/** A request to return info needed to import the suggestion.
|
||||
*
|
||||
* @param suggestion the suggestion to import
|
||||
*/
|
||||
final case class ImportSuggestionRequest(suggestion: Suggestion)
|
||||
extends ApiRequest
|
||||
with ToLogString {
|
||||
|
||||
/** @inheritdoc */
|
||||
override def toLogString(shouldMask: Boolean): String =
|
||||
s"ImportSuggestionRequest(suggestion=${suggestion.toLogString(shouldMask)})"
|
||||
}
|
||||
|
||||
/** The result of the import request.
|
||||
*
|
||||
* @param module the definition module of the symbol
|
||||
* @param symbol the resolved symbol
|
||||
* @param exports the list of exports of the symbol
|
||||
*/
|
||||
final case class ImportSuggestionResponse(
|
||||
module: String,
|
||||
symbol: String,
|
||||
exports: Seq[Export]
|
||||
) extends ApiResponse
|
||||
|
||||
/** A request for the type hierarchy graph. */
|
||||
final case class GetTypeGraphRequest() extends ApiRequest
|
||||
|
||||
|
@ -80,6 +80,27 @@ final class SuggestionBuilder[A: IndexedSource](val source: A) {
|
||||
)
|
||||
go(tree ++= methodOpt.map(Tree.Node(_, subforest)), scope)
|
||||
|
||||
case IR.Module.Scope.Definition.Method
|
||||
.Conversion(
|
||||
IR.Name.MethodReference(_, _, _, _, _),
|
||||
IR.Name.Literal(sourceTypeName, _, _, _, _, _),
|
||||
IR.Function.Lambda(args, body, _, _, _, _),
|
||||
_,
|
||||
_,
|
||||
_
|
||||
) if ConversionsEnabled =>
|
||||
val typeSignature = ir.getMetadata(TypeSignatures)
|
||||
val conversion = buildConversion(
|
||||
body.getExternalId,
|
||||
module,
|
||||
args,
|
||||
sourceTypeName,
|
||||
doc,
|
||||
typeSignature,
|
||||
bindings
|
||||
)
|
||||
go(tree += Tree.Node(conversion, Vector()), scope)
|
||||
|
||||
case IR.Expression.Binding(
|
||||
name,
|
||||
IR.Function.Lambda(args, body, _, _, _, _),
|
||||
@ -167,7 +188,34 @@ final class SuggestionBuilder[A: IndexedSource](val source: A) {
|
||||
)
|
||||
}
|
||||
|
||||
/** Build a function suggestion */
|
||||
/** Build a conversion suggestion. */
|
||||
private def buildConversion(
|
||||
externalId: Option[IR.ExternalId],
|
||||
module: QualifiedName,
|
||||
args: Seq[IR.DefinitionArgument],
|
||||
sourceTypeName: String,
|
||||
doc: Option[String],
|
||||
typeSignature: Option[TypeSignatures.Metadata],
|
||||
bindings: Option[BindingAnalysis.Metadata]
|
||||
): Suggestion.Conversion = {
|
||||
val typeSig = buildTypeSignatureFromMetadata(typeSignature, bindings)
|
||||
val (methodArgs, returnTypeDef) =
|
||||
buildFunctionArguments(args, typeSig)
|
||||
Suggestion.Conversion(
|
||||
externalId = externalId,
|
||||
module = module.toString,
|
||||
arguments = methodArgs,
|
||||
sourceType = sourceTypeName,
|
||||
returnType = buildReturnType(returnTypeDef),
|
||||
documentation = doc,
|
||||
documentationHtml = doc.map(
|
||||
DocParserWrapper.runOnPureDoc(_, Suggestion.Kind.Conversion.From)
|
||||
),
|
||||
reexport = None
|
||||
)
|
||||
}
|
||||
|
||||
/** Build a function suggestion. */
|
||||
private def buildFunction(
|
||||
externalId: Option[IR.ExternalId],
|
||||
module: QualifiedName,
|
||||
@ -569,6 +617,9 @@ final class SuggestionBuilder[A: IndexedSource](val source: A) {
|
||||
|
||||
object SuggestionBuilder {
|
||||
|
||||
/** TODO[DB] enable conversions when they get the runtime support. */
|
||||
private val ConversionsEnabled: Boolean = false
|
||||
|
||||
/** Create the suggestion builder.
|
||||
*
|
||||
* @param source the text source
|
||||
|
@ -50,9 +50,6 @@ object CommandFactory {
|
||||
case payload: Api.VerifyModulesIndexRequest =>
|
||||
new VerifyModulesIndexCmd(request.requestId, payload)
|
||||
|
||||
case payload: Api.ImportSuggestionRequest =>
|
||||
new ImportSuggestionCmd(request.requestId, payload)
|
||||
|
||||
case _: Api.GetTypeGraphRequest =>
|
||||
new GetTypeGraphCommand(request.requestId)
|
||||
|
||||
|
@ -1,126 +0,0 @@
|
||||
package org.enso.interpreter.instrument.command
|
||||
|
||||
import org.enso.compiler.data.BindingsMap
|
||||
import org.enso.compiler.pass.analyse.BindingAnalysis
|
||||
import org.enso.interpreter.instrument.execution.RuntimeContext
|
||||
import org.enso.interpreter.runtime.Module
|
||||
import org.enso.polyglot.Suggestion
|
||||
import org.enso.polyglot.runtime.Runtime.Api
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
/** A command that gathers info required for suggestion import.
|
||||
*
|
||||
* @param maybeRequestId an option with request id
|
||||
* @param request a request for suggestion import
|
||||
*/
|
||||
final class ImportSuggestionCmd(
|
||||
maybeRequestId: Option[Api.RequestId],
|
||||
val request: Api.ImportSuggestionRequest
|
||||
) extends Command(maybeRequestId) {
|
||||
|
||||
import ImportSuggestionCmd._
|
||||
|
||||
/** Executes a request.
|
||||
*
|
||||
* @param ctx contains suppliers of services to perform a request
|
||||
* @param ec execution context
|
||||
*/
|
||||
override def execute(implicit
|
||||
ctx: RuntimeContext,
|
||||
ec: ExecutionContext
|
||||
): Future[Unit] = Future {
|
||||
val suggestion = request.suggestion
|
||||
reply(
|
||||
Api.ImportSuggestionResponse(
|
||||
suggestion.module,
|
||||
suggestion.name,
|
||||
findExports.sortBy(_.depth).map(_.export)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/** Find re-exports of the given symbol.
|
||||
*
|
||||
* @param ctx contains suppliers of services to perform a request
|
||||
*/
|
||||
private def findExports(implicit ctx: RuntimeContext): Seq[ExportResult] = {
|
||||
val suggestion = request.suggestion
|
||||
val topScope =
|
||||
ctx.executionService.getContext.getCompiler.context.getTopScope
|
||||
val builder = Vector.newBuilder[ExportResult]
|
||||
|
||||
topScope.getModules
|
||||
.stream()
|
||||
.filter(isCompiled)
|
||||
.forEach { module =>
|
||||
module.getIr.getMetadata(BindingAnalysis).foreach { bindings =>
|
||||
builder ++= getQualifiedExport(
|
||||
module,
|
||||
suggestion,
|
||||
bindings
|
||||
)
|
||||
builder ++= getUnqualifiedExport(module, suggestion, bindings)
|
||||
}
|
||||
}
|
||||
|
||||
builder.result()
|
||||
}
|
||||
|
||||
/** Extract the qualified export from the bindings map. */
|
||||
private def getQualifiedExport(
|
||||
module: Module,
|
||||
suggestion: Suggestion,
|
||||
bindings: BindingsMap
|
||||
): Option[ExportResult] = {
|
||||
bindings.resolvedExports
|
||||
.find(_.module.getName.toString == suggestion.module)
|
||||
.filter(_.exportedAs.isDefined)
|
||||
.map { exportedModule =>
|
||||
val qualified = Api.Export.Qualified(
|
||||
module.getName.toString,
|
||||
exportedModule.exportedAs
|
||||
)
|
||||
ExportResult(qualified, getDepth(module))
|
||||
}
|
||||
}
|
||||
|
||||
/** Extract the unqualified export from the bindings map. */
|
||||
private def getUnqualifiedExport(
|
||||
module: Module,
|
||||
suggestion: Suggestion,
|
||||
bindings: BindingsMap
|
||||
): Option[ExportResult] = {
|
||||
bindings.exportedSymbols.get(suggestion.name).flatMap { resolvedExports =>
|
||||
resolvedExports
|
||||
.find(_.module.getName.toString == suggestion.module)
|
||||
.map { _ =>
|
||||
val unqualified = Api.Export.Unqualified(module.getName.toString)
|
||||
ExportResult(unqualified, getDepth(module))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private def getDepth(module: Module): Int =
|
||||
module.getName.path.size
|
||||
|
||||
private def isCompiled(module: Module): Boolean =
|
||||
module.getIr != null
|
||||
}
|
||||
|
||||
object ImportSuggestionCmd {
|
||||
|
||||
/** Module that exports target symbol.
|
||||
*
|
||||
* @param name the module name
|
||||
*/
|
||||
private case class ExportingModule(name: String)
|
||||
|
||||
/** An intermediate result of exports resolution.
|
||||
*
|
||||
* @param export the module export
|
||||
* @param depth how nested is the exporting module
|
||||
*/
|
||||
private case class ExportResult(export: Api.Export, depth: Int)
|
||||
|
||||
}
|
@ -442,11 +442,12 @@ class EnsureCompiledJob(protected val files: Iterable[File])
|
||||
|
||||
private def isSuggestionGlobal(suggestion: Suggestion): Boolean =
|
||||
suggestion match {
|
||||
case _: Suggestion.Module => true
|
||||
case _: Suggestion.Atom => true
|
||||
case _: Suggestion.Method => true
|
||||
case _: Suggestion.Function => false
|
||||
case _: Suggestion.Local => false
|
||||
case _: Suggestion.Module => true
|
||||
case _: Suggestion.Atom => true
|
||||
case _: Suggestion.Method => true
|
||||
case _: Suggestion.Conversion => true
|
||||
case _: Suggestion.Function => false
|
||||
case _: Suggestion.Local => false
|
||||
}
|
||||
|
||||
private def getCompilationStatus(
|
||||
|
@ -647,6 +647,188 @@ class SuggestionBuilderTest extends CompilerTest {
|
||||
)
|
||||
}
|
||||
|
||||
"build conversion method for simple type" in {
|
||||
pending
|
||||
implicit val moduleContext: ModuleContext = freshModuleContext
|
||||
|
||||
val code =
|
||||
"""type MyAtom a
|
||||
|
|
||||
|## My conversion
|
||||
|MyAtom.from : Number -> MyAtom
|
||||
|MyAtom.from a = MyAtom a
|
||||
|""".stripMargin
|
||||
val module = code.preprocessModule
|
||||
|
||||
build(code, module) shouldEqual Tree.Root(
|
||||
Vector(
|
||||
ModuleNode,
|
||||
Tree.Node(
|
||||
Suggestion.Atom(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "MyType",
|
||||
arguments = Seq(
|
||||
Suggestion
|
||||
.Argument("a", SuggestionBuilder.Any, false, false, None)
|
||||
),
|
||||
returnType = "Unnamed.Test.MyType",
|
||||
documentation = None,
|
||||
documentationHtml = None
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
Tree.Node(
|
||||
Suggestion.Method(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "a",
|
||||
arguments = List(
|
||||
Suggestion
|
||||
.Argument("this", "Unnamed.Test.MyType", false, false, None)
|
||||
),
|
||||
selfType = "Unnamed.Test.MyType",
|
||||
returnType = SuggestionBuilder.Any,
|
||||
documentation = None,
|
||||
documentationHtml = None
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
Tree.Node(
|
||||
Suggestion.Conversion(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
arguments = Seq(
|
||||
Suggestion.Argument("a", "Number", false, false, None)
|
||||
),
|
||||
returnType = "Unnamed.Test.MyType",
|
||||
sourceType = "Number",
|
||||
documentation = Some(" My conversion"),
|
||||
documentationHtml =
|
||||
Some(DocParserWrapper.runOnPureDoc(" My conversion", "from"))
|
||||
),
|
||||
Vector()
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
"build conersion method for complex type" in {
|
||||
pending
|
||||
implicit val moduleContext: ModuleContext = freshModuleContext
|
||||
val code =
|
||||
"""type MyMaybe
|
||||
| type Some a
|
||||
| type None
|
||||
|
|
||||
|type Newtype x
|
||||
|
|
||||
|## My conversion method
|
||||
|Newtype.from : MyMaybe -> Newtype
|
||||
|Newtype.from opt = case opt of
|
||||
| Some a -> Newtype a
|
||||
| None -> Newtype 0
|
||||
|""".stripMargin
|
||||
val module = code.preprocessModule
|
||||
|
||||
build(code, module) shouldEqual Tree.Root(
|
||||
Vector(
|
||||
ModuleNode,
|
||||
Tree.Node(
|
||||
Suggestion.Atom(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "Some",
|
||||
arguments = Seq(
|
||||
Suggestion
|
||||
.Argument("a", SuggestionBuilder.Any, false, false, None)
|
||||
),
|
||||
returnType = "Unnamed.Test.MyMaybe",
|
||||
documentation = None,
|
||||
documentationHtml = None
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
Tree.Node(
|
||||
Suggestion.Method(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "a",
|
||||
arguments = List(
|
||||
Suggestion
|
||||
.Argument("this", "Unnamed.Test.MyMaybe", false, false, None)
|
||||
),
|
||||
selfType = "Unnamed.Test.MyMaybe",
|
||||
returnType = SuggestionBuilder.Any,
|
||||
documentation = None,
|
||||
documentationHtml = None
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
Tree.Node(
|
||||
Suggestion.Atom(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "None",
|
||||
arguments = Seq(),
|
||||
returnType = "Unnamed.Test.None",
|
||||
documentation = None,
|
||||
documentationHtml = None
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
Tree.Node(
|
||||
Suggestion.Atom(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "Newtype",
|
||||
arguments = Seq(
|
||||
Suggestion
|
||||
.Argument("x", SuggestionBuilder.Any, false, false, None)
|
||||
),
|
||||
returnType = "Unnamed.Test.Newtype",
|
||||
documentation = None,
|
||||
documentationHtml = None
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
Tree.Node(
|
||||
Suggestion.Method(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "x",
|
||||
arguments = List(
|
||||
Suggestion
|
||||
.Argument("this", "Unnamed.Test.Newtype", false, false, None)
|
||||
),
|
||||
selfType = "Unnamed.Test.NewType",
|
||||
returnType = SuggestionBuilder.Any,
|
||||
documentation = None,
|
||||
documentationHtml = None
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
Tree.Node(
|
||||
Suggestion.Conversion(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
arguments = Seq(
|
||||
Suggestion
|
||||
.Argument("opt", "Unnamed.Test.MyMaybe", false, false, None)
|
||||
),
|
||||
returnType = "Unnamed.Test.MyType",
|
||||
sourceType = "Unnamed.Test.MyMaybe",
|
||||
documentation = Some(" My conversion method"),
|
||||
documentationHtml = Some(
|
||||
DocParserWrapper.runOnPureDoc(" My conversion method", "from")
|
||||
)
|
||||
),
|
||||
Vector()
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
"build function simple" in {
|
||||
implicit val moduleContext: ModuleContext = freshModuleContext
|
||||
|
||||
|
@ -22,11 +22,12 @@ object SuggestionRandom {
|
||||
|
||||
def nextSuggestion(): Suggestion = {
|
||||
nextKind() match {
|
||||
case Suggestion.Kind.Module => nextSuggestionModule()
|
||||
case Suggestion.Kind.Atom => nextSuggestionAtom()
|
||||
case Suggestion.Kind.Method => nextSuggestionMethod()
|
||||
case Suggestion.Kind.Function => nextSuggestionFunction()
|
||||
case Suggestion.Kind.Local => nextSuggestionLocal()
|
||||
case Suggestion.Kind.Module => nextSuggestionModule()
|
||||
case Suggestion.Kind.Atom => nextSuggestionAtom()
|
||||
case Suggestion.Kind.Method => nextSuggestionMethod()
|
||||
case Suggestion.Kind.Conversion => nextSuggestionMethod()
|
||||
case Suggestion.Kind.Function => nextSuggestionFunction()
|
||||
case Suggestion.Kind.Local => nextSuggestionLocal()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1066,6 +1066,41 @@ final class SqlSuggestionsRepo(val db: SqlDatabase)(implicit
|
||||
reexport = reexport
|
||||
)
|
||||
row -> args
|
||||
case Suggestion.Conversion(
|
||||
expr,
|
||||
module,
|
||||
args,
|
||||
sourceType,
|
||||
returnType,
|
||||
doc,
|
||||
docHtml,
|
||||
reexport
|
||||
) =>
|
||||
val firstArg = Suggestion.Argument(
|
||||
Suggestion.Kind.Conversion.From,
|
||||
sourceType,
|
||||
false,
|
||||
false,
|
||||
None
|
||||
)
|
||||
val row = SuggestionRow(
|
||||
id = None,
|
||||
externalIdLeast = expr.map(_.getLeastSignificantBits),
|
||||
externalIdMost = expr.map(_.getMostSignificantBits),
|
||||
kind = SuggestionKind.CONVERSION,
|
||||
module = module,
|
||||
name = toConversionMethodName(sourceType, returnType),
|
||||
selfType = SelfTypeColumn.EMPTY,
|
||||
returnType = returnType,
|
||||
documentation = doc,
|
||||
documentationHtml = docHtml,
|
||||
scopeStartLine = ScopeColumn.EMPTY,
|
||||
scopeStartOffset = ScopeColumn.EMPTY,
|
||||
scopeEndLine = ScopeColumn.EMPTY,
|
||||
scopeEndOffset = ScopeColumn.EMPTY,
|
||||
reexport = reexport
|
||||
)
|
||||
row -> (firstArg +: args)
|
||||
case Suggestion.Function(expr, module, name, args, returnType, scope) =>
|
||||
val row = SuggestionRow(
|
||||
id = None,
|
||||
@ -1106,6 +1141,13 @@ final class SqlSuggestionsRepo(val db: SqlDatabase)(implicit
|
||||
row -> Seq()
|
||||
}
|
||||
|
||||
/** Create the method name for conversion */
|
||||
private def toConversionMethodName(
|
||||
sourceType: String,
|
||||
returnType: String
|
||||
): String =
|
||||
s"${Suggestion.Kind.Conversion.From}_${sourceType}_${returnType}"
|
||||
|
||||
/** Convert the argument to a row in the arguments table. */
|
||||
private def toArgumentRow(
|
||||
suggestionId: Long,
|
||||
@ -1168,6 +1210,18 @@ final class SqlSuggestionsRepo(val db: SqlDatabase)(implicit
|
||||
documentationHtml = suggestion.documentationHtml,
|
||||
reexport = suggestion.reexport
|
||||
)
|
||||
case SuggestionKind.CONVERSION =>
|
||||
Suggestion.Conversion(
|
||||
externalId =
|
||||
toUUID(suggestion.externalIdLeast, suggestion.externalIdMost),
|
||||
module = suggestion.module,
|
||||
arguments = arguments.sortBy(_.index).tail.map(toArgument),
|
||||
sourceType = arguments.minBy(_.index).tpe,
|
||||
returnType = suggestion.returnType,
|
||||
documentation = suggestion.documentation,
|
||||
documentationHtml = suggestion.documentationHtml,
|
||||
reexport = suggestion.reexport
|
||||
)
|
||||
case SuggestionKind.FUNCTION =>
|
||||
Suggestion.Function(
|
||||
externalId =
|
||||
|
@ -83,11 +83,12 @@ case class ModuleVersionRow(module: String, digest: Array[Byte])
|
||||
/** The type of a suggestion. */
|
||||
object SuggestionKind {
|
||||
|
||||
val MODULE: Byte = 0
|
||||
val ATOM: Byte = 1
|
||||
val METHOD: Byte = 2
|
||||
val FUNCTION: Byte = 3
|
||||
val LOCAL: Byte = 4
|
||||
val MODULE: Byte = 0
|
||||
val ATOM: Byte = 1
|
||||
val METHOD: Byte = 2
|
||||
val FUNCTION: Byte = 3
|
||||
val LOCAL: Byte = 4
|
||||
val CONVERSION: Byte = 5
|
||||
|
||||
/** Create a database suggestion kind.
|
||||
*
|
||||
@ -96,11 +97,12 @@ object SuggestionKind {
|
||||
*/
|
||||
def apply(kind: Suggestion.Kind): Byte =
|
||||
kind match {
|
||||
case Suggestion.Kind.Module => MODULE
|
||||
case Suggestion.Kind.Atom => ATOM
|
||||
case Suggestion.Kind.Method => METHOD
|
||||
case Suggestion.Kind.Function => FUNCTION
|
||||
case Suggestion.Kind.Local => LOCAL
|
||||
case Suggestion.Kind.Module => MODULE
|
||||
case Suggestion.Kind.Atom => ATOM
|
||||
case Suggestion.Kind.Method => METHOD
|
||||
case Suggestion.Kind.Conversion => CONVERSION
|
||||
case Suggestion.Kind.Function => FUNCTION
|
||||
case Suggestion.Kind.Local => LOCAL
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,6 +67,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -79,6 +80,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -91,6 +93,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -115,6 +118,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -133,6 +137,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -155,6 +160,8 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.function,
|
||||
suggestion.local,
|
||||
@ -169,10 +176,15 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
ids(1) shouldBe a[None.type]
|
||||
ids(2) shouldBe a[Some[_]]
|
||||
ids(3) shouldBe a[None.type]
|
||||
ids(4) shouldBe a[Some[_]]
|
||||
ids(5) shouldBe a[None.type]
|
||||
ids(6) shouldBe a[Some[_]]
|
||||
ids(7) shouldBe a[None.type]
|
||||
all.map(_.suggestion) should contain theSameElementsAs Seq(
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -222,6 +234,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -241,6 +254,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -255,11 +269,12 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
|
||||
"remove all suggestions" taggedAs Retry in withRepo { repo =>
|
||||
val action = for {
|
||||
(_, Seq(_, id1, _, _, id4)) <- repo.insertAll(
|
||||
(_, Seq(_, id1, _, _, _, id4)) <- repo.insertAll(
|
||||
Seq(
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -402,6 +417,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
_ <- repo.insert(suggestion.module)
|
||||
_ <- repo.insert(suggestion.atom)
|
||||
_ <- repo.insert(suggestion.method)
|
||||
_ <- repo.insert(suggestion.conversion)
|
||||
_ <- repo.insert(suggestion.function)
|
||||
Some(id4) <- repo.insert(suggestion.local)
|
||||
res <-
|
||||
@ -417,11 +433,12 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
"update suggestion external id" taggedAs Retry in withRepo { repo =>
|
||||
val newUuid = UUID.randomUUID()
|
||||
val action = for {
|
||||
(v1, Seq(_, _, id1, _, _)) <- repo.insertAll(
|
||||
(v1, Seq(_, _, id1, _, _, _)) <- repo.insertAll(
|
||||
Seq(
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -447,11 +464,12 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
"update suggestion removing external id" taggedAs Retry in withRepo {
|
||||
repo =>
|
||||
val action = for {
|
||||
(v1, Seq(_, _, _, id1, _)) <- repo.insertAll(
|
||||
(v1, Seq(_, _, _, _, id1, _)) <- repo.insertAll(
|
||||
Seq(
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -477,11 +495,12 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
"update suggestion return type" taggedAs Retry in withRepo { repo =>
|
||||
val newReturnType = "NewType"
|
||||
val action = for {
|
||||
(v1, Seq(_, _, _, id1, _)) <- repo.insertAll(
|
||||
(v1, Seq(_, _, _, _, id1, _)) <- repo.insertAll(
|
||||
Seq(
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -507,11 +526,12 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
"update suggestion atom documentation" taggedAs Retry in withRepo { repo =>
|
||||
val newDoc = "My Doc"
|
||||
val action = for {
|
||||
(v1, Seq(_, id1, _, _, _)) <- repo.insertAll(
|
||||
(v1, Seq(_, id1, _, _, _, _)) <- repo.insertAll(
|
||||
Seq(
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -538,11 +558,12 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
repo =>
|
||||
val newDoc = "My Doc"
|
||||
val action = for {
|
||||
(v1, Seq(_, id1, _, _, _)) <- repo.insertAll(
|
||||
(v1, Seq(_, id1, _, _, _, _)) <- repo.insertAll(
|
||||
Seq(
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -571,11 +592,12 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
repo =>
|
||||
val newDoc = "My Doc"
|
||||
val action = for {
|
||||
(v1, Seq(id1, _, _, _, _)) <- repo.insertAll(
|
||||
(v1, Seq(id1, _, _, _, _, _)) <- repo.insertAll(
|
||||
Seq(
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -602,11 +624,12 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
repo =>
|
||||
val newDoc = "My Doc"
|
||||
val action = for {
|
||||
(v1, Seq(id1, _, _, _, _)) <- repo.insertAll(
|
||||
(v1, Seq(id1, _, _, _, _, _)) <- repo.insertAll(
|
||||
Seq(
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -631,14 +654,83 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
)
|
||||
}
|
||||
|
||||
"update suggestion removing documentation" taggedAs Retry in withRepo {
|
||||
"update suggestion conversion documentation" taggedAs Retry in withRepo {
|
||||
repo =>
|
||||
val newDoc = "My Doc"
|
||||
val action = for {
|
||||
(v1, Seq(_, id1, _, _, _)) <- repo.insertAll(
|
||||
(v1, Seq(_, _, _, id1, _, _)) <- repo.insertAll(
|
||||
Seq(
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
)
|
||||
(v2, id2) <- repo.update(
|
||||
suggestion.conversion,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(Some(newDoc)),
|
||||
None,
|
||||
None,
|
||||
None
|
||||
)
|
||||
s <- repo.select(id1.get)
|
||||
} yield (v1, id1, v2, id2, s)
|
||||
val (v1, id1, v2, id2, s) = Await.result(action, Timeout)
|
||||
v1 should not equal v2
|
||||
id1 shouldEqual id2
|
||||
s shouldEqual Some(
|
||||
suggestion.conversion.copy(documentation = Some(newDoc))
|
||||
)
|
||||
}
|
||||
|
||||
"update suggestion conversion HTML documentation" taggedAs Retry in withRepo {
|
||||
repo =>
|
||||
val newDoc = "My Doc"
|
||||
val action = for {
|
||||
(v1, Seq(_, _, _, id1, _, _)) <- repo.insertAll(
|
||||
Seq(
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
)
|
||||
(v2, id2) <- repo.update(
|
||||
suggestion.conversion,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(Some(newDoc)),
|
||||
None,
|
||||
None
|
||||
)
|
||||
s <- repo.select(id1.get)
|
||||
} yield (v1, id1, v2, id2, s)
|
||||
val (v1, id1, v2, id2, s) = Await.result(action, Timeout)
|
||||
v1 should not equal v2
|
||||
id1 shouldEqual id2
|
||||
s shouldEqual Some(
|
||||
suggestion.conversion.copy(documentationHtml = Some(newDoc))
|
||||
)
|
||||
}
|
||||
|
||||
"update suggestion removing documentation" taggedAs Retry in withRepo {
|
||||
repo =>
|
||||
val action = for {
|
||||
(v1, Seq(_, id1, _, _, _, _)) <- repo.insertAll(
|
||||
Seq(
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -664,11 +756,12 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
"update suggestion removing HTML documentation" taggedAs Retry in withRepo {
|
||||
repo =>
|
||||
val action = for {
|
||||
(v1, Seq(_, id1, _, _, _)) <- repo.insertAll(
|
||||
(v1, Seq(_, id1, _, _, _, _)) <- repo.insertAll(
|
||||
Seq(
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -697,11 +790,12 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
Suggestion.Position(42, 43)
|
||||
)
|
||||
val action = for {
|
||||
(v1, Seq(_, _, _, _, id1)) <- repo.insertAll(
|
||||
(v1, Seq(_, _, _, _, _, id1)) <- repo.insertAll(
|
||||
Seq(
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -729,11 +823,12 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
Api.SuggestionArgumentAction.Remove(1)
|
||||
)
|
||||
val action = for {
|
||||
(v1, Seq(_, id1, _, _, _)) <- repo.insertAll(
|
||||
(v1, Seq(_, id1, _, _, _, _)) <- repo.insertAll(
|
||||
Seq(
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -764,11 +859,12 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
Api.SuggestionArgumentAction.Add(3, suggestion.atom.arguments(1))
|
||||
)
|
||||
val action = for {
|
||||
(v1, Seq(_, id1, _, _, _)) <- repo.insertAll(
|
||||
(v1, Seq(_, id1, _, _, _, _)) <- repo.insertAll(
|
||||
Seq(
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -807,11 +903,12 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
)
|
||||
)
|
||||
val action = for {
|
||||
(v1, Seq(_, id1, _, _, _)) <- repo.insertAll(
|
||||
(v1, Seq(_, id1, _, _, _, _)) <- repo.insertAll(
|
||||
Seq(
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -846,6 +943,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -872,6 +970,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
_ <- repo.insert(suggestion.module)
|
||||
_ <- repo.insert(suggestion.atom)
|
||||
_ <- repo.insert(suggestion.method)
|
||||
_ <- repo.insert(suggestion.conversion)
|
||||
_ <- repo.insert(suggestion.function)
|
||||
id4 <- repo.insert(suggestion.local)
|
||||
v1 <- repo.currentVersion
|
||||
@ -891,6 +990,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
_ <- repo.insert(suggestion.module)
|
||||
_ <- repo.insert(suggestion.atom)
|
||||
_ <- repo.insert(suggestion.method)
|
||||
_ <- repo.insert(suggestion.conversion)
|
||||
_ <- repo.insert(suggestion.function)
|
||||
_ <- repo.insert(suggestion.local)
|
||||
v1 <- repo.currentVersion
|
||||
@ -912,6 +1012,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -925,14 +1026,22 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
xs1 should contain theSameElementsAs ids.flatten.map((_, newModuleName))
|
||||
xs2 should contain theSameElementsAs Seq(ids(2)).flatten
|
||||
.map((_, newSelfType))
|
||||
xs3 should contain theSameElementsAs Seq(ids(3), ids(4)).flatten
|
||||
.map((_, newReturnType))
|
||||
xs4 should contain theSameElementsAs Seq()
|
||||
xs3 should contain theSameElementsAs Seq(ids(3), ids(4), ids(5)).flatten
|
||||
.map {
|
||||
case id if ids(3).get == id => (id, "Best.Main.Bar")
|
||||
case id => (id, newReturnType)
|
||||
}
|
||||
xs4 should contain theSameElementsAs Seq((ids(3).get, 0, "Best.Main.Foo"))
|
||||
res.map(_.suggestion) should contain theSameElementsAs Seq(
|
||||
suggestion.module.copy(module = newModuleName),
|
||||
suggestion.atom.copy(module = newModuleName),
|
||||
suggestion.method
|
||||
.copy(module = newModuleName, selfType = newSelfType),
|
||||
suggestion.conversion.copy(
|
||||
module = newModuleName,
|
||||
sourceType = "Best.Main.Foo",
|
||||
returnType = "Best.Main.Bar"
|
||||
),
|
||||
suggestion.function
|
||||
.copy(module = newModuleName, returnType = newReturnType),
|
||||
suggestion.local
|
||||
@ -952,6 +1061,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
suggestion.module,
|
||||
atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -971,15 +1081,25 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
}
|
||||
xs2 should contain theSameElementsAs Seq(ids(2)).flatten
|
||||
.map((_, newSelfType))
|
||||
xs3 should contain theSameElementsAs Seq(ids(3), ids(4)).flatten
|
||||
.map((_, newReturnType))
|
||||
xs4 should contain theSameElementsAs Seq()
|
||||
xs3 should contain theSameElementsAs Seq(ids(3), ids(4), ids(5)).flatten
|
||||
.map {
|
||||
case id if ids(3).get == id => (id, "Best.Main.Bar")
|
||||
case id => (id, newReturnType)
|
||||
}
|
||||
xs4 should contain theSameElementsAs Seq(
|
||||
(ids(3).get, 0, "Best.Main.Foo")
|
||||
)
|
||||
res.map(_.suggestion) should contain theSameElementsAs Seq(
|
||||
suggestion.module
|
||||
.copy(module = newModuleName),
|
||||
atom.copy(module = "Best.Main.Test.Main"),
|
||||
suggestion.method
|
||||
.copy(module = newModuleName, selfType = newSelfType),
|
||||
suggestion.conversion.copy(
|
||||
module = newModuleName,
|
||||
sourceType = "Best.Main.Foo",
|
||||
returnType = "Best.Main.Bar"
|
||||
),
|
||||
suggestion.function
|
||||
.copy(module = newModuleName, returnType = newReturnType),
|
||||
suggestion.local
|
||||
@ -993,12 +1113,13 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
val newFooModuleName = "Best.Foo"
|
||||
val newReturnTypeName = "Best.Main.MyType"
|
||||
|
||||
val module = suggestion.module.copy(module = "Test.Main")
|
||||
val atom = suggestion.atom.copy(module = "Test.Main")
|
||||
val method = suggestion.method.copy(module = "Test.Foo")
|
||||
val function = suggestion.function.copy(module = "Bar.Main")
|
||||
val local = suggestion.local.copy(module = "Bar.Main")
|
||||
val all = Seq(module, atom, method, function, local)
|
||||
val module = suggestion.module.copy(module = "Test.Main")
|
||||
val atom = suggestion.atom.copy(module = "Test.Main")
|
||||
val method = suggestion.method.copy(module = "Test.Foo")
|
||||
val conversion = suggestion.conversion.copy(module = "Test.Foo")
|
||||
val function = suggestion.function.copy(module = "Bar.Main")
|
||||
val local = suggestion.local.copy(module = "Bar.Main")
|
||||
val all = Seq(module, atom, method, conversion, function, local)
|
||||
val action = for {
|
||||
(_, ids) <- repo.insertAll(all)
|
||||
(_, xs1, xs2, xs3, xs4) <- repo.renameProject("Test", "Best")
|
||||
@ -1008,7 +1129,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
val (ids, xs1, xs2, xs3, xs4, res) = Await.result(action, Timeout)
|
||||
|
||||
xs1 should contain theSameElementsAs ids
|
||||
.zip(Seq(module, atom, method))
|
||||
.zip(Seq(module, atom, method, conversion))
|
||||
.flatMap {
|
||||
case (idOpt, _: Suggestion.Module) =>
|
||||
idOpt.map((_, newMainModuleName))
|
||||
@ -1019,13 +1140,23 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
}
|
||||
xs2 should contain theSameElementsAs Seq(ids(2)).flatten
|
||||
.map((_, newMainModuleName))
|
||||
xs3 should contain theSameElementsAs Seq(ids(3), ids(4)).flatten
|
||||
.map((_, newReturnTypeName))
|
||||
xs4 should contain theSameElementsAs Seq()
|
||||
xs3 should contain theSameElementsAs Seq(ids(3), ids(4), ids(5)).flatten
|
||||
.map {
|
||||
case id if ids(3).get == id => (id, "Best.Main.Bar")
|
||||
case id => (id, newReturnTypeName)
|
||||
}
|
||||
xs4 should contain theSameElementsAs Seq(
|
||||
(ids(3).get, 0, "Best.Main.Foo")
|
||||
)
|
||||
res.map(_.suggestion) should contain theSameElementsAs Seq(
|
||||
module.copy(module = newMainModuleName),
|
||||
atom.copy(module = newMainModuleName),
|
||||
method.copy(module = newFooModuleName, selfType = newMainModuleName),
|
||||
module.copy(module = newMainModuleName),
|
||||
atom.copy(module = newMainModuleName),
|
||||
method.copy(module = newFooModuleName, selfType = newMainModuleName),
|
||||
suggestion.conversion.copy(
|
||||
module = newFooModuleName,
|
||||
sourceType = "Best.Main.Foo",
|
||||
returnType = "Best.Main.Bar"
|
||||
),
|
||||
function.copy(returnType = newReturnTypeName),
|
||||
local.copy(returnType = newReturnTypeName)
|
||||
)
|
||||
@ -1055,6 +1186,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -1069,10 +1201,16 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
xs1 should contain theSameElementsAs ids.flatten.map((_, newModuleName))
|
||||
xs2 should contain theSameElementsAs Seq(ids(2)).flatten
|
||||
.map((_, newSelfType))
|
||||
xs3 should contain theSameElementsAs Seq(ids(3), ids(4)).flatten
|
||||
.map((_, newReturnType))
|
||||
xs4 should contain theSameElementsAs Seq(ids(2)).flatMap {
|
||||
_.map((_, 1, newArgumentType))
|
||||
xs3 should contain theSameElementsAs Seq(ids(3), ids(4), ids(5)).flatten
|
||||
.map {
|
||||
case id if ids(3).get == id => (id, "Best.Main.Bar")
|
||||
case id => (id, newReturnType)
|
||||
}
|
||||
xs4 should contain theSameElementsAs Seq(ids(2), ids(3)).flatMap {
|
||||
_.map {
|
||||
case id if ids(3).get == id => (id, 0, "Best.Main.Foo")
|
||||
case id => (id, 1, newArgumentType)
|
||||
}
|
||||
}
|
||||
res.map(_.suggestion) should contain theSameElementsAs Seq(
|
||||
suggestion.module.copy(module = newModuleName),
|
||||
@ -1088,6 +1226,11 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
)
|
||||
}
|
||||
),
|
||||
suggestion.conversion.copy(
|
||||
module = newModuleName,
|
||||
sourceType = "Best.Main.Foo",
|
||||
returnType = "Best.Main.Bar"
|
||||
),
|
||||
suggestion.function
|
||||
.copy(module = newModuleName, returnType = newReturnType),
|
||||
suggestion.local
|
||||
@ -1142,6 +1285,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -1182,6 +1326,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -1221,6 +1366,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -1256,6 +1402,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
suggestion.module,
|
||||
suggestion.atom,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
@ -1275,6 +1422,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
_ <- repo.insert(suggestion.module)
|
||||
_ <- repo.insert(suggestion.atom)
|
||||
_ <- repo.insert(suggestion.method)
|
||||
_ <- repo.insert(suggestion.conversion)
|
||||
_ <- repo.insert(suggestion.function)
|
||||
_ <- repo.insert(suggestion.local)
|
||||
res <- repo.search(None, Seq(), None, None, None)
|
||||
@ -1289,13 +1437,21 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
id0 <- repo.insert(suggestion.module)
|
||||
id1 <- repo.insert(suggestion.atom)
|
||||
id2 <- repo.insert(suggestion.method)
|
||||
id3 <- repo.insert(suggestion.function)
|
||||
id4 <- repo.insert(suggestion.local)
|
||||
id3 <- repo.insert(suggestion.conversion)
|
||||
id4 <- repo.insert(suggestion.function)
|
||||
id5 <- repo.insert(suggestion.local)
|
||||
res <- repo.search(Some("Test.Main"), Seq(), None, None, None)
|
||||
} yield (id0, id1, id2, id3, id4, res._2)
|
||||
} yield (id0, id1, id2, id3, id4, id5, res._2)
|
||||
|
||||
val (id0, id1, id2, id3, id4, res) = Await.result(action, Timeout)
|
||||
res should contain theSameElementsAs Seq(id0, id1, id2, id3, id4).flatten
|
||||
val (id0, id1, id2, id3, id4, id5, res) = Await.result(action, Timeout)
|
||||
res should contain theSameElementsAs Seq(
|
||||
id0,
|
||||
id1,
|
||||
id2,
|
||||
id3,
|
||||
id4,
|
||||
id5
|
||||
).flatten
|
||||
}
|
||||
|
||||
"search suggestion by empty module" taggedAs Retry in withRepo { repo =>
|
||||
@ -1303,10 +1459,11 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
id0 <- repo.insert(suggestion.module)
|
||||
id1 <- repo.insert(suggestion.atom)
|
||||
id2 <- repo.insert(suggestion.method)
|
||||
id3 <- repo.insert(suggestion.conversion)
|
||||
_ <- repo.insert(suggestion.function)
|
||||
_ <- repo.insert(suggestion.local)
|
||||
res <- repo.search(Some(""), Seq(), None, None, None)
|
||||
} yield (res._2, Seq(id0, id1, id2))
|
||||
} yield (res._2, Seq(id0, id1, id2, id3))
|
||||
|
||||
val (res, globals) = Await.result(action, Timeout)
|
||||
res should contain theSameElementsAs globals.flatten
|
||||
@ -1317,6 +1474,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
_ <- repo.insert(suggestion.module)
|
||||
_ <- repo.insert(suggestion.atom)
|
||||
id2 <- repo.insert(suggestion.method)
|
||||
_ <- repo.insert(suggestion.conversion)
|
||||
_ <- repo.insert(suggestion.function)
|
||||
_ <- repo.insert(suggestion.local)
|
||||
res <- repo.search(None, Seq("Test.Main"), None, None, None)
|
||||
@ -1331,6 +1489,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
_ <- repo.insert(suggestion.module)
|
||||
_ <- repo.insert(suggestion.atom)
|
||||
_ <- repo.insert(suggestion.method)
|
||||
_ <- repo.insert(suggestion.conversion)
|
||||
id3 <- repo.insert(suggestion.function)
|
||||
id4 <- repo.insert(suggestion.local)
|
||||
res <- repo.search(None, Seq(), Some("Test.Main.MyType"), None, None)
|
||||
@ -1346,6 +1505,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
_ <- repo.insert(suggestion.module)
|
||||
id1 <- repo.insert(suggestion.atom)
|
||||
_ <- repo.insert(suggestion.method)
|
||||
_ <- repo.insert(suggestion.conversion)
|
||||
_ <- repo.insert(suggestion.function)
|
||||
id4 <- repo.insert(suggestion.local)
|
||||
res <- repo.search(None, Seq(), None, Some(kinds), None)
|
||||
@ -1360,6 +1520,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
_ <- repo.insert(suggestion.module)
|
||||
_ <- repo.insert(suggestion.atom)
|
||||
_ <- repo.insert(suggestion.method)
|
||||
_ <- repo.insert(suggestion.conversion)
|
||||
_ <- repo.insert(suggestion.function)
|
||||
_ <- repo.insert(suggestion.local)
|
||||
res <- repo.search(None, Seq(), None, Some(Seq()), None)
|
||||
@ -1374,6 +1535,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
id0 <- repo.insert(suggestion.module)
|
||||
id1 <- repo.insert(suggestion.atom)
|
||||
id2 <- repo.insert(suggestion.method)
|
||||
id3 <- repo.insert(suggestion.conversion)
|
||||
_ <- repo.insert(suggestion.function)
|
||||
_ <- repo.insert(suggestion.local)
|
||||
res <-
|
||||
@ -1384,10 +1546,10 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
None,
|
||||
Some(Suggestion.Position(99, 42))
|
||||
)
|
||||
} yield (id0, id1, id2, res._2)
|
||||
} yield (id0, id1, id2, id3, res._2)
|
||||
|
||||
val (id0, id1, id2, res) = Await.result(action, Timeout)
|
||||
res should contain theSameElementsAs Seq(id0, id1, id2).flatten
|
||||
val (id0, id1, id2, id3, res) = Await.result(action, Timeout)
|
||||
res should contain theSameElementsAs Seq(id0, id1, id2, id3).flatten
|
||||
}
|
||||
|
||||
"search suggestion local by scope" taggedAs Retry in withRepo { repo =>
|
||||
@ -1395,14 +1557,15 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
id0 <- repo.insert(suggestion.module)
|
||||
id1 <- repo.insert(suggestion.atom)
|
||||
id2 <- repo.insert(suggestion.method)
|
||||
id3 <- repo.insert(suggestion.function)
|
||||
id3 <- repo.insert(suggestion.conversion)
|
||||
id4 <- repo.insert(suggestion.function)
|
||||
_ <- repo.insert(suggestion.local)
|
||||
res <-
|
||||
repo.search(None, Seq(), None, None, Some(Suggestion.Position(1, 5)))
|
||||
} yield (id0, id1, id2, id3, res._2)
|
||||
} yield (id0, id1, id2, id3, id4, res._2)
|
||||
|
||||
val (id0, id1, id2, id3, res) = Await.result(action, Timeout)
|
||||
res should contain theSameElementsAs Seq(id0, id1, id2, id3).flatten
|
||||
val (id0, id1, id2, id3, id4, res) = Await.result(action, Timeout)
|
||||
res should contain theSameElementsAs Seq(id0, id1, id2, id3, id4).flatten
|
||||
}
|
||||
|
||||
"search suggestion by module and self type" taggedAs Retry in withRepo {
|
||||
@ -1411,6 +1574,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
_ <- repo.insert(suggestion.module)
|
||||
_ <- repo.insert(suggestion.atom)
|
||||
id2 <- repo.insert(suggestion.method)
|
||||
_ <- repo.insert(suggestion.conversion)
|
||||
_ <- repo.insert(suggestion.function)
|
||||
_ <- repo.insert(suggestion.local)
|
||||
res <- repo.search(
|
||||
@ -1433,6 +1597,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
_ <- repo.insert(suggestion.module)
|
||||
_ <- repo.insert(suggestion.atom)
|
||||
_ <- repo.insert(suggestion.method)
|
||||
_ <- repo.insert(suggestion.conversion)
|
||||
_ <- repo.insert(suggestion.function)
|
||||
id4 <- repo.insert(suggestion.local)
|
||||
res <- repo.search(
|
||||
@ -1454,6 +1619,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
_ <- repo.insert(suggestion.module)
|
||||
_ <- repo.insert(suggestion.atom)
|
||||
_ <- repo.insert(suggestion.method)
|
||||
_ <- repo.insert(suggestion.conversion)
|
||||
_ <- repo.insert(suggestion.function)
|
||||
id4 <- repo.insert(suggestion.local)
|
||||
res <- repo.search(
|
||||
@ -1475,6 +1641,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
_ <- repo.insert(suggestion.module)
|
||||
id1 <- repo.insert(suggestion.atom)
|
||||
_ <- repo.insert(suggestion.method)
|
||||
_ <- repo.insert(suggestion.conversion)
|
||||
_ <- repo.insert(suggestion.function)
|
||||
_ <- repo.insert(suggestion.local)
|
||||
res <- repo.search(
|
||||
@ -1496,6 +1663,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
_ <- repo.insert(suggestion.module)
|
||||
_ <- repo.insert(suggestion.atom)
|
||||
_ <- repo.insert(suggestion.method)
|
||||
_ <- repo.insert(suggestion.conversion)
|
||||
_ <- repo.insert(suggestion.function)
|
||||
_ <- repo.insert(suggestion.local)
|
||||
res <- repo.search(
|
||||
@ -1518,6 +1686,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
_ <- repo.insert(suggestion.module)
|
||||
_ <- repo.insert(suggestion.atom)
|
||||
_ <- repo.insert(suggestion.method)
|
||||
_ <- repo.insert(suggestion.conversion)
|
||||
_ <- repo.insert(suggestion.function)
|
||||
id4 <- repo.insert(suggestion.local)
|
||||
res <- repo.search(
|
||||
@ -1540,6 +1709,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
_ <- repo.insert(suggestion.module)
|
||||
_ <- repo.insert(suggestion.atom)
|
||||
_ <- repo.insert(suggestion.method)
|
||||
_ <- repo.insert(suggestion.conversion)
|
||||
_ <- repo.insert(suggestion.function)
|
||||
id4 <- repo.insert(suggestion.local)
|
||||
res <- repo.search(
|
||||
@ -1565,6 +1735,7 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
_ <- repo.insert(suggestion.module)
|
||||
_ <- repo.insert(suggestion.atom)
|
||||
_ <- repo.insert(suggestion.method)
|
||||
_ <- repo.insert(suggestion.conversion)
|
||||
_ <- repo.insert(suggestion.function)
|
||||
_ <- repo.insert(suggestion.local)
|
||||
res <- repo.search(
|
||||
@ -1619,6 +1790,18 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
reexport = None
|
||||
)
|
||||
|
||||
val conversion: Suggestion.Conversion =
|
||||
Suggestion.Conversion(
|
||||
externalId = Some(UUID.randomUUID()),
|
||||
module = "Test.Main",
|
||||
arguments = Seq(),
|
||||
sourceType = "Test.Main.Foo",
|
||||
returnType = "Test.Main.Bar",
|
||||
documentation = None,
|
||||
documentationHtml = None,
|
||||
reexport = None
|
||||
)
|
||||
|
||||
val function: Suggestion.Function =
|
||||
Suggestion.Function(
|
||||
externalId = Some(UUID.randomUUID()),
|
||||
|
Loading…
Reference in New Issue
Block a user