mirror of
https://github.com/enso-org/enso.git
synced 2024-11-23 06:34:35 +03:00
Documentation for functions and locals (#4029)
Add documentation for functions and locals to suggestions database.
This commit is contained in:
parent
bc66753627
commit
2cd880f43d
@ -602,6 +602,15 @@ interface Function {
|
||||
|
||||
/** The scope where the function is defined. */
|
||||
scope: SuggestionEntryScope;
|
||||
|
||||
/** The documentation string. */
|
||||
documentation?: string;
|
||||
|
||||
/** The rendered HTML of the documentation string. */
|
||||
documentationHtml?: string;
|
||||
|
||||
/** The documentation string divided into sections. */
|
||||
documentationSections?: DocSection[];
|
||||
}
|
||||
|
||||
interface Local {
|
||||
@ -619,6 +628,15 @@ interface Local {
|
||||
|
||||
/** The scope where the value is defined. */
|
||||
scope: SuggestionEntryScope;
|
||||
|
||||
/** The documentation string. */
|
||||
documentation?: string;
|
||||
|
||||
/** The rendered HTML of the documentation string. */
|
||||
documentationHtml?: string;
|
||||
|
||||
/** The documentation string divided into sections. */
|
||||
documentationSections?: DocSection[];
|
||||
}
|
||||
```
|
||||
|
||||
@ -940,6 +958,11 @@ interface Modify {
|
||||
*/
|
||||
documentation?: FieldUpdate<String>;
|
||||
|
||||
/**
|
||||
* New documentation sections.
|
||||
*/
|
||||
documentationSections?: FieldUpdate<DocSection[]>;
|
||||
|
||||
/**
|
||||
* The scope to update.
|
||||
*/
|
||||
|
@ -408,20 +408,22 @@ object SearchProtocol {
|
||||
* @param returnType the return type to update
|
||||
* @param documentation the documentation string to update
|
||||
* @param documentationHtml the HTML documentation to update
|
||||
* @param documentationSections the documentation sections to update
|
||||
* @param scope the scope to update
|
||||
* @param reexport the module reexporting the suggestion
|
||||
*/
|
||||
case class Modify(
|
||||
id: SuggestionId,
|
||||
externalId: Option[FieldUpdate[Suggestion.ExternalId]] = None,
|
||||
arguments: Option[Seq[SuggestionArgumentUpdate]] = None,
|
||||
module: Option[FieldUpdate[String]] = None,
|
||||
selfType: Option[FieldUpdate[String]] = None,
|
||||
returnType: Option[FieldUpdate[String]] = None,
|
||||
documentation: Option[FieldUpdate[String]] = None,
|
||||
documentationHtml: Option[FieldUpdate[String]] = None,
|
||||
scope: Option[FieldUpdate[Suggestion.Scope]] = None,
|
||||
reexport: Option[FieldUpdate[String]] = None
|
||||
externalId: Option[FieldUpdate[Suggestion.ExternalId]] = None,
|
||||
arguments: Option[Seq[SuggestionArgumentUpdate]] = None,
|
||||
module: Option[FieldUpdate[String]] = None,
|
||||
selfType: Option[FieldUpdate[String]] = None,
|
||||
returnType: Option[FieldUpdate[String]] = None,
|
||||
documentation: Option[FieldUpdate[String]] = None,
|
||||
documentationHtml: Option[FieldUpdate[String]] = None,
|
||||
documentationSections: Option[FieldUpdate[Seq[DocSection]]] = None,
|
||||
scope: Option[FieldUpdate[Suggestion.Scope]] = None,
|
||||
reexport: Option[FieldUpdate[String]] = None
|
||||
) extends SuggestionsDatabaseUpdate
|
||||
|
||||
implicit val decoder: Decoder[SuggestionsDatabaseUpdate] =
|
||||
|
@ -591,8 +591,11 @@ final class SuggestionsHandler(
|
||||
externalId = m.externalId.map(fieldUpdateOption),
|
||||
arguments = m.arguments.map(_.map(toApiArgumentAction)),
|
||||
returnType = m.returnType.map(fieldUpdate),
|
||||
scope = m.scope.map(fieldUpdate),
|
||||
documentation = m.documentation.map(fieldUpdateOption),
|
||||
scope = m.scope.map(fieldUpdate)
|
||||
documentationSections = m.documentation.map(
|
||||
fieldUpdateMapOption(docSectionsBuilder.build)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -625,7 +628,7 @@ final class SuggestionsHandler(
|
||||
/** Construct the field update object from an optional value.
|
||||
*
|
||||
* @param value the optional value
|
||||
* @return the field update object representint the value update
|
||||
* @return the field update object representing the value update
|
||||
*/
|
||||
private def fieldUpdateOption[A](value: Option[A]): FieldUpdate[A] =
|
||||
value match {
|
||||
@ -633,6 +636,20 @@ final class SuggestionsHandler(
|
||||
case None => FieldUpdate(FieldAction.Remove, None)
|
||||
}
|
||||
|
||||
/** Construct the field update object from an optional value.
|
||||
*
|
||||
* @param f the mapping function
|
||||
* @param value the optional value
|
||||
* @return the field update object representing the value update
|
||||
*/
|
||||
private def fieldUpdateMapOption[A, B](
|
||||
f: A => B
|
||||
)(value: Option[A]): FieldUpdate[B] =
|
||||
value match {
|
||||
case Some(value) => FieldUpdate(FieldAction.Set, Some(f(value)))
|
||||
case None => FieldUpdate(FieldAction.Remove, None)
|
||||
}
|
||||
|
||||
/** Construct the field update object from and update value.
|
||||
*
|
||||
* @param value the update value
|
||||
@ -731,8 +748,13 @@ final class SuggestionsHandler(
|
||||
val docSections = conversion.documentation.map(docSectionsBuilder.build)
|
||||
conversion.copy(documentationSections = docSections)
|
||||
|
||||
case _: Suggestion.Function => suggestion
|
||||
case _: Suggestion.Local => suggestion
|
||||
case function: Suggestion.Function =>
|
||||
val docSections = function.documentation.map(docSectionsBuilder.build)
|
||||
function.copy(documentationSections = docSections)
|
||||
|
||||
case local: Suggestion.Local =>
|
||||
val docSections = local.documentation.map(docSectionsBuilder.build)
|
||||
local.copy(documentationSections = docSections)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,10 @@ object Suggestions {
|
||||
),
|
||||
returnType = "IO",
|
||||
scope =
|
||||
Suggestion.Scope(Suggestion.Position(1, 9), Suggestion.Position(1, 22))
|
||||
Suggestion.Scope(Suggestion.Position(1, 9), Suggestion.Position(1, 22)),
|
||||
documentation = Some("My Function"),
|
||||
documentationHtml = None,
|
||||
documentationSections = Some(docSectionsBuilder.build("My Function"))
|
||||
)
|
||||
|
||||
val local: Suggestion.Local = Suggestion.Local(
|
||||
@ -96,7 +99,8 @@ object Suggestions {
|
||||
name = "x",
|
||||
returnType = "Number",
|
||||
scope =
|
||||
Suggestion.Scope(Suggestion.Position(21, 0), Suggestion.Position(89, 0))
|
||||
Suggestion.Scope(Suggestion.Position(21, 0), Suggestion.Position(89, 0)),
|
||||
documentation = None
|
||||
)
|
||||
|
||||
val methodOnAny: Suggestion.Method = Suggestion.Method(
|
||||
|
@ -307,7 +307,14 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec {
|
||||
"line" : 1,
|
||||
"character" : 22
|
||||
}
|
||||
}
|
||||
},
|
||||
"documentation" : "My Function",
|
||||
"documentationSections" : [
|
||||
{
|
||||
"type" : "paragraph",
|
||||
"body" : "My Function"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -503,7 +510,14 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec {
|
||||
"line" : 1,
|
||||
"character" : 22
|
||||
}
|
||||
}
|
||||
},
|
||||
"documentation" : "My Function",
|
||||
"documentationSections" : [
|
||||
{
|
||||
"type" : "paragraph",
|
||||
"body" : "My Function"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -41,10 +41,11 @@ import java.util.UUID
|
||||
)
|
||||
sealed trait Suggestion extends ToLogString {
|
||||
|
||||
def externalId: Option[Suggestion.ExternalId]
|
||||
def module: String
|
||||
def name: String
|
||||
def returnType: String
|
||||
def externalId: Option[Suggestion.ExternalId]
|
||||
def module: String
|
||||
def name: String
|
||||
def returnType: String
|
||||
def documentation: Option[String]
|
||||
}
|
||||
|
||||
object Suggestion {
|
||||
@ -121,20 +122,6 @@ object Suggestion {
|
||||
}
|
||||
}
|
||||
|
||||
/** Documentation extractor */
|
||||
object Documentation {
|
||||
def apply(suggestion: Suggestion): Option[String] =
|
||||
suggestion match {
|
||||
case module: Module => module.documentation
|
||||
case tpe: Type => tpe.documentation
|
||||
case constructor: Constructor => constructor.documentation
|
||||
case method: Method => method.documentation
|
||||
case conv: Conversion => conv.documentation
|
||||
case _: Function => None
|
||||
case _: Local => None
|
||||
}
|
||||
}
|
||||
|
||||
/** An argument of an atom or a function.
|
||||
*
|
||||
* @param name the argument name
|
||||
@ -185,6 +172,7 @@ object Suggestion {
|
||||
* @param module the fully qualified module name
|
||||
* @param documentation the documentation string
|
||||
* @param documentationHtml the documentation rendered as HTML
|
||||
* @param documentationSections the documentation parsed into sections
|
||||
* @param reexport the module re-exporting this module
|
||||
*/
|
||||
case class Module(
|
||||
@ -222,6 +210,7 @@ object Suggestion {
|
||||
* @param parentType qualified name of the parent type
|
||||
* @param documentation the documentation string
|
||||
* @param documentationHtml the documentation rendered as HTML
|
||||
* @param documentationSections the documentation parsed into sections
|
||||
* @param reexport the module re-exporting this atom
|
||||
*/
|
||||
case class Type(
|
||||
@ -261,6 +250,7 @@ object Suggestion {
|
||||
* @param returnType the type of an atom
|
||||
* @param documentation the documentation string
|
||||
* @param documentationHtml the documentation rendered as HTML
|
||||
* @param documentationSections the documentation parsed into sections
|
||||
* @param reexport the module re-exporting this atom
|
||||
*/
|
||||
case class Constructor(
|
||||
@ -300,6 +290,7 @@ object Suggestion {
|
||||
* @param isStatic the flag indicating whether a method is static or instance
|
||||
* @param documentation the documentation string
|
||||
* @param documentationHtml the documentation rendered as HTML
|
||||
* @param documentationSections the documentation parsed into sections
|
||||
* @param reexport the module re-exporting this method
|
||||
*/
|
||||
case class Method(
|
||||
@ -340,6 +331,7 @@ object Suggestion {
|
||||
* @param returnType the return type of a conversion
|
||||
* @param documentation the documentation string
|
||||
* @param documentationHtml the documentation rendered as HTML
|
||||
* @param documentationSections the documentation parsed into sections
|
||||
* @param reexport the module re-exporting this conversion
|
||||
*/
|
||||
case class Conversion(
|
||||
@ -378,6 +370,9 @@ object Suggestion {
|
||||
* @param arguments the function arguments
|
||||
* @param returnType the return type of a function
|
||||
* @param scope the scope where the function is defined
|
||||
* @param documentation the documentation string
|
||||
* @param documentationHtml the documentation rendered as HTML
|
||||
* @param documentationSections the documentation parsed into sections
|
||||
*/
|
||||
case class Function(
|
||||
externalId: Option[ExternalId],
|
||||
@ -385,7 +380,10 @@ object Suggestion {
|
||||
name: String,
|
||||
arguments: Seq[Argument],
|
||||
returnType: String,
|
||||
scope: Scope
|
||||
scope: Scope,
|
||||
documentation: Option[String],
|
||||
documentationHtml: Option[String] = None,
|
||||
documentationSections: Option[List[DocSection]] = None
|
||||
) extends Suggestion
|
||||
with ToLogString {
|
||||
|
||||
@ -397,7 +395,8 @@ object Suggestion {
|
||||
s"name=$name," +
|
||||
s"arguments=${arguments.map(_.toLogString(shouldMask))}," +
|
||||
s"returnType=$returnType," +
|
||||
s"scope=$scope" +
|
||||
s"scope=$scope," +
|
||||
s"documentation=$documentation" +
|
||||
")"
|
||||
}
|
||||
|
||||
@ -408,13 +407,19 @@ object Suggestion {
|
||||
* @param name the name of a value
|
||||
* @param returnType the type of a local value
|
||||
* @param scope the scope where the value is defined
|
||||
* @param documentation the documentation string
|
||||
* @param documentationHtml the documentation rendered as HTML
|
||||
* @param documentationSections the documentation parsed into sections
|
||||
*/
|
||||
case class Local(
|
||||
externalId: Option[ExternalId],
|
||||
module: String,
|
||||
name: String,
|
||||
returnType: String,
|
||||
scope: Scope
|
||||
scope: Scope,
|
||||
documentation: Option[String],
|
||||
documentationHtml: Option[String] = None,
|
||||
documentationSections: Option[List[DocSection]] = None
|
||||
) extends Suggestion {
|
||||
|
||||
/** @inheritdoc */
|
||||
@ -424,7 +429,8 @@ object Suggestion {
|
||||
s"module=$module," +
|
||||
s"name=$name," +
|
||||
s"returnType=$returnType," +
|
||||
s"scope=$scope" +
|
||||
s"scope=$scope," +
|
||||
s"documentation=$documentation" +
|
||||
s")"
|
||||
}
|
||||
}
|
||||
|
@ -360,10 +360,12 @@ class RuntimeStdlibTest
|
||||
)
|
||||
) =>
|
||||
updates.toVector.foreach { update =>
|
||||
val docstring = Suggestion.Documentation(update.suggestion)
|
||||
docstring.foreach(
|
||||
context.docsGenerator.generate(_, update.suggestion.name)
|
||||
)
|
||||
update.suggestion.documentation.foreach { documentation =>
|
||||
context.docsGenerator.generate(
|
||||
documentation,
|
||||
update.suggestion.name
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -247,7 +247,8 @@ class RuntimeSuggestionUpdatesTest
|
||||
Suggestion.Scope(
|
||||
Suggestion.Position(2, 6),
|
||||
Suggestion.Position(4, 16)
|
||||
)
|
||||
),
|
||||
None
|
||||
),
|
||||
Api.SuggestionAction.Add()
|
||||
),
|
||||
@ -328,7 +329,8 @@ class RuntimeSuggestionUpdatesTest
|
||||
Suggestion.Scope(
|
||||
Suggestion.Position(2, 6),
|
||||
Suggestion.Position(4, 16)
|
||||
)
|
||||
),
|
||||
None
|
||||
),
|
||||
Api.SuggestionAction.Modify(scope =
|
||||
Some(
|
||||
@ -351,7 +353,8 @@ class RuntimeSuggestionUpdatesTest
|
||||
Suggestion.Scope(
|
||||
Suggestion.Position(2, 6),
|
||||
Suggestion.Position(5, 18)
|
||||
)
|
||||
),
|
||||
None
|
||||
),
|
||||
Api.SuggestionAction.Add()
|
||||
),
|
||||
@ -429,7 +432,8 @@ class RuntimeSuggestionUpdatesTest
|
||||
Suggestion.Scope(
|
||||
Suggestion.Position(2, 6),
|
||||
Suggestion.Position(5, 18)
|
||||
)
|
||||
),
|
||||
None
|
||||
),
|
||||
Api.SuggestionAction.Modify(scope =
|
||||
Some(
|
||||
@ -452,7 +456,8 @@ class RuntimeSuggestionUpdatesTest
|
||||
Suggestion.Scope(
|
||||
Suggestion.Position(2, 6),
|
||||
Suggestion.Position(5, 18)
|
||||
)
|
||||
),
|
||||
None
|
||||
),
|
||||
Api.SuggestionAction.Modify(
|
||||
returnType = Some(ConstantsGen.NUMBER),
|
||||
@ -540,7 +545,8 @@ class RuntimeSuggestionUpdatesTest
|
||||
Suggestion.Scope(
|
||||
Suggestion.Position(2, 6),
|
||||
Suggestion.Position(6, 18)
|
||||
)
|
||||
),
|
||||
None
|
||||
),
|
||||
Api.SuggestionAction.Modify(scope =
|
||||
Some(
|
||||
@ -563,7 +569,8 @@ class RuntimeSuggestionUpdatesTest
|
||||
Suggestion.Scope(
|
||||
Suggestion.Position(2, 6),
|
||||
Suggestion.Position(6, 18)
|
||||
)
|
||||
),
|
||||
None
|
||||
),
|
||||
Api.SuggestionAction.Modify(scope =
|
||||
Some(
|
||||
@ -808,7 +815,8 @@ class RuntimeSuggestionUpdatesTest
|
||||
Suggestion.Scope(
|
||||
Suggestion.Position(4, 6),
|
||||
Suggestion.Position(8, 11)
|
||||
)
|
||||
),
|
||||
None
|
||||
),
|
||||
Api.SuggestionAction.Add()
|
||||
),
|
||||
|
@ -165,6 +165,7 @@ final class SuggestionBuilder[A: IndexedSource](
|
||||
name,
|
||||
args,
|
||||
scope.location.get,
|
||||
doc,
|
||||
typeSignature
|
||||
)
|
||||
val subforest = go(
|
||||
@ -181,6 +182,7 @@ final class SuggestionBuilder[A: IndexedSource](
|
||||
module,
|
||||
name.name,
|
||||
scope.location.get,
|
||||
doc,
|
||||
typeSignature
|
||||
)
|
||||
val subforest = go(
|
||||
@ -264,18 +266,20 @@ final class SuggestionBuilder[A: IndexedSource](
|
||||
name: IR.Name,
|
||||
args: Seq[IR.DefinitionArgument],
|
||||
location: Location,
|
||||
doc: Option[String],
|
||||
typeSignature: Option[TypeSignatures.Metadata]
|
||||
): Suggestion.Function = {
|
||||
val typeSig = buildTypeSignatureFromMetadata(typeSignature)
|
||||
val (methodArgs, returnTypeDef) =
|
||||
buildFunctionArguments(args, typeSig)
|
||||
Suggestion.Function(
|
||||
externalId = externalId,
|
||||
module = module.toString,
|
||||
name = name.name,
|
||||
arguments = methodArgs,
|
||||
returnType = buildReturnType(returnTypeDef),
|
||||
scope = buildScope(location)
|
||||
externalId = externalId,
|
||||
module = module.toString,
|
||||
name = name.name,
|
||||
arguments = methodArgs,
|
||||
returnType = buildReturnType(returnTypeDef),
|
||||
scope = buildScope(location),
|
||||
documentation = doc
|
||||
)
|
||||
}
|
||||
|
||||
@ -285,16 +289,18 @@ final class SuggestionBuilder[A: IndexedSource](
|
||||
module: QualifiedName,
|
||||
name: String,
|
||||
location: Location,
|
||||
doc: Option[String],
|
||||
typeSignature: Option[TypeSignatures.Metadata]
|
||||
): Suggestion.Local = {
|
||||
val typeSig = buildTypeSignatureFromMetadata(typeSignature)
|
||||
val (_, returnTypeDef) = buildFunctionArguments(Seq(), typeSig)
|
||||
Suggestion.Local(
|
||||
externalId,
|
||||
module.toString,
|
||||
name,
|
||||
buildReturnType(returnTypeDef),
|
||||
buildScope(location)
|
||||
externalId = externalId,
|
||||
module = module.toString,
|
||||
name = name,
|
||||
returnType = buildReturnType(returnTypeDef),
|
||||
scope = buildScope(location),
|
||||
documentation = doc
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -222,6 +222,9 @@ object SuggestionDiff {
|
||||
if (e1.scope != e2.scope) {
|
||||
op = op.copy(scope = Some(e2.scope))
|
||||
}
|
||||
if (e1.documentation != e2.documentation) {
|
||||
op = op.copy(documentation = Some(e2.documentation))
|
||||
}
|
||||
Api.SuggestionUpdate(e1, op)
|
||||
}
|
||||
|
||||
@ -239,6 +242,9 @@ object SuggestionDiff {
|
||||
if (e1.scope != e2.scope) {
|
||||
op = op.copy(scope = Some(e2.scope))
|
||||
}
|
||||
if (e1.documentation != e2.documentation) {
|
||||
op = op.copy(documentation = Some(e2.documentation))
|
||||
}
|
||||
Api.SuggestionUpdate(e1, op)
|
||||
}
|
||||
}
|
||||
|
@ -317,7 +317,11 @@ class SuggestionBuilderTest extends AnyWordSpecLike with Matchers {
|
||||
"x",
|
||||
"Number",
|
||||
Suggestion
|
||||
.Scope(Suggestion.Position(0, 9), Suggestion.Position(4, 9))
|
||||
.Scope(
|
||||
Suggestion.Position(0, 9),
|
||||
Suggestion.Position(4, 9)
|
||||
),
|
||||
None
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
@ -328,7 +332,11 @@ class SuggestionBuilderTest extends AnyWordSpecLike with Matchers {
|
||||
"y",
|
||||
SuggestionBuilder.Any,
|
||||
Suggestion
|
||||
.Scope(Suggestion.Position(0, 9), Suggestion.Position(4, 9))
|
||||
.Scope(
|
||||
Suggestion.Position(0, 9),
|
||||
Suggestion.Position(4, 9)
|
||||
),
|
||||
None
|
||||
),
|
||||
Vector()
|
||||
)
|
||||
@ -939,7 +947,8 @@ class SuggestionBuilderTest extends AnyWordSpecLike with Matchers {
|
||||
scope = Suggestion.Scope(
|
||||
Suggestion.Position(0, 6),
|
||||
Suggestion.Position(2, 10)
|
||||
)
|
||||
),
|
||||
None
|
||||
),
|
||||
Vector()
|
||||
)
|
||||
@ -988,7 +997,8 @@ class SuggestionBuilderTest extends AnyWordSpecLike with Matchers {
|
||||
scope = Suggestion.Scope(
|
||||
Suggestion.Position(0, 6),
|
||||
Suggestion.Position(4, 10)
|
||||
)
|
||||
),
|
||||
documentation = None
|
||||
),
|
||||
Vector(
|
||||
Tree.Node(
|
||||
@ -1000,7 +1010,8 @@ class SuggestionBuilderTest extends AnyWordSpecLike with Matchers {
|
||||
scope = Suggestion.Scope(
|
||||
Suggestion.Position(1, 11),
|
||||
Suggestion.Position(3, 9)
|
||||
)
|
||||
),
|
||||
documentation = None
|
||||
),
|
||||
Vector()
|
||||
)
|
||||
@ -1049,7 +1060,8 @@ class SuggestionBuilderTest extends AnyWordSpecLike with Matchers {
|
||||
scope = Suggestion.Scope(
|
||||
Suggestion.Position(0, 6),
|
||||
Suggestion.Position(3, 10)
|
||||
)
|
||||
),
|
||||
documentation = None
|
||||
),
|
||||
Vector()
|
||||
)
|
||||
@ -1118,7 +1130,63 @@ class SuggestionBuilderTest extends AnyWordSpecLike with Matchers {
|
||||
scope = Suggestion.Scope(
|
||||
Suggestion.Position(2, 6),
|
||||
Suggestion.Position(5, 10)
|
||||
)
|
||||
),
|
||||
documentation = None
|
||||
),
|
||||
Vector()
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
"build function with documentation" in {
|
||||
|
||||
val code =
|
||||
"""main =
|
||||
| ## Foo documentation.
|
||||
| foo a = a + 1
|
||||
| foo 42
|
||||
|""".stripMargin
|
||||
val module = code.preprocessModule
|
||||
|
||||
build(code, module) shouldEqual Tree.Root(
|
||||
Vector(
|
||||
ModuleNode,
|
||||
Tree.Node(
|
||||
Suggestion.Method(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "main",
|
||||
arguments = Seq(),
|
||||
selfType = "Unnamed.Test",
|
||||
returnType = SuggestionBuilder.Any,
|
||||
isStatic = true,
|
||||
documentation = None
|
||||
),
|
||||
Vector(
|
||||
Tree.Node(
|
||||
Suggestion.Function(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "foo",
|
||||
arguments = Seq(
|
||||
Suggestion
|
||||
.Argument(
|
||||
"a",
|
||||
SuggestionBuilder.Any,
|
||||
false,
|
||||
false,
|
||||
None
|
||||
)
|
||||
),
|
||||
returnType = SuggestionBuilder.Any,
|
||||
scope = Suggestion.Scope(
|
||||
Suggestion.Position(0, 6),
|
||||
Suggestion.Position(3, 10)
|
||||
),
|
||||
documentation = Some(" Foo documentation.")
|
||||
),
|
||||
Vector()
|
||||
)
|
||||
@ -1161,7 +1229,8 @@ class SuggestionBuilderTest extends AnyWordSpecLike with Matchers {
|
||||
scope = Suggestion.Scope(
|
||||
Suggestion.Position(0, 6),
|
||||
Suggestion.Position(2, 7)
|
||||
)
|
||||
),
|
||||
documentation = None
|
||||
),
|
||||
Vector()
|
||||
)
|
||||
@ -1206,7 +1275,8 @@ class SuggestionBuilderTest extends AnyWordSpecLike with Matchers {
|
||||
scope = Suggestion.Scope(
|
||||
Suggestion.Position(0, 6),
|
||||
Suggestion.Position(4, 7)
|
||||
)
|
||||
),
|
||||
documentation = None
|
||||
),
|
||||
Vector(
|
||||
Tree.Node(
|
||||
@ -1218,7 +1288,8 @@ class SuggestionBuilderTest extends AnyWordSpecLike with Matchers {
|
||||
scope = Suggestion.Scope(
|
||||
Suggestion.Position(1, 9),
|
||||
Suggestion.Position(3, 9)
|
||||
)
|
||||
),
|
||||
documentation = None
|
||||
),
|
||||
Vector()
|
||||
)
|
||||
@ -1264,7 +1335,8 @@ class SuggestionBuilderTest extends AnyWordSpecLike with Matchers {
|
||||
scope = Suggestion.Scope(
|
||||
Suggestion.Position(0, 6),
|
||||
Suggestion.Position(3, 7)
|
||||
)
|
||||
),
|
||||
documentation = None
|
||||
),
|
||||
Vector()
|
||||
)
|
||||
@ -1322,7 +1394,53 @@ class SuggestionBuilderTest extends AnyWordSpecLike with Matchers {
|
||||
scope = Suggestion.Scope(
|
||||
Suggestion.Position(2, 6),
|
||||
Suggestion.Position(5, 7)
|
||||
)
|
||||
),
|
||||
documentation = None
|
||||
),
|
||||
Vector()
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
"build local with documentation" in {
|
||||
|
||||
val code =
|
||||
"""main =
|
||||
| ## This is foo.
|
||||
| foo = 42
|
||||
| foo
|
||||
|""".stripMargin
|
||||
val module = code.preprocessModule
|
||||
|
||||
build(code, module) shouldEqual Tree.Root(
|
||||
Vector(
|
||||
ModuleNode,
|
||||
Tree.Node(
|
||||
Suggestion.Method(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "main",
|
||||
arguments = Seq(),
|
||||
selfType = "Unnamed.Test",
|
||||
returnType = SuggestionBuilder.Any,
|
||||
isStatic = true,
|
||||
documentation = None
|
||||
),
|
||||
Vector(
|
||||
Tree.Node(
|
||||
Suggestion.Local(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "foo",
|
||||
returnType = SuggestionBuilder.Any,
|
||||
scope = Suggestion.Scope(
|
||||
Suggestion.Position(0, 6),
|
||||
Suggestion.Position(3, 7)
|
||||
),
|
||||
documentation = Some(" This is foo.")
|
||||
),
|
||||
Vector()
|
||||
)
|
||||
@ -2187,7 +2305,8 @@ class SuggestionBuilderTest extends AnyWordSpecLike with Matchers {
|
||||
scope = Suggestion.Scope(
|
||||
Suggestion.Position(0, 6),
|
||||
Suggestion.Position(2, 28)
|
||||
)
|
||||
),
|
||||
documentation = None
|
||||
),
|
||||
Vector()
|
||||
)
|
||||
@ -2236,7 +2355,8 @@ class SuggestionBuilderTest extends AnyWordSpecLike with Matchers {
|
||||
scope = Suggestion.Scope(
|
||||
Suggestion.Position(0, 6),
|
||||
Suggestion.Position(2, 18)
|
||||
)
|
||||
),
|
||||
documentation = None
|
||||
),
|
||||
Vector()
|
||||
)
|
||||
|
@ -77,21 +77,23 @@ object SuggestionRandom {
|
||||
|
||||
def nextSuggestionFunction(): Suggestion.Function =
|
||||
Suggestion.Function(
|
||||
externalId = optional(UUID.randomUUID()),
|
||||
module = "Test.Main",
|
||||
name = nextString(),
|
||||
arguments = Seq(),
|
||||
returnType = nextString(),
|
||||
scope = nextScope()
|
||||
externalId = optional(UUID.randomUUID()),
|
||||
module = "Test.Main",
|
||||
name = nextString(),
|
||||
arguments = Seq(),
|
||||
returnType = nextString(),
|
||||
scope = nextScope(),
|
||||
documentation = optional(nextString())
|
||||
)
|
||||
|
||||
def nextSuggestionLocal(): Suggestion.Local =
|
||||
Suggestion.Local(
|
||||
externalId = optional(UUID.randomUUID()),
|
||||
module = "Test.Main",
|
||||
name = nextString(),
|
||||
returnType = nextString(),
|
||||
scope = nextScope()
|
||||
externalId = optional(UUID.randomUUID()),
|
||||
module = "Test.Main",
|
||||
name = nextString(),
|
||||
returnType = nextString(),
|
||||
scope = nextScope(),
|
||||
documentation = optional(nextString())
|
||||
)
|
||||
|
||||
def nextScope(): Suggestion.Scope =
|
||||
|
@ -1129,7 +1129,17 @@ final class SqlSuggestionsRepo(val db: SqlDatabase)(implicit
|
||||
reexport = reexport
|
||||
)
|
||||
row -> (firstArg +: args)
|
||||
case Suggestion.Function(expr, module, name, args, returnType, scope) =>
|
||||
case Suggestion.Function(
|
||||
expr,
|
||||
module,
|
||||
name,
|
||||
args,
|
||||
returnType,
|
||||
scope,
|
||||
doc,
|
||||
_,
|
||||
_
|
||||
) =>
|
||||
val row = SuggestionRow(
|
||||
id = None,
|
||||
externalIdLeast = expr.map(_.getLeastSignificantBits),
|
||||
@ -1141,7 +1151,7 @@ final class SqlSuggestionsRepo(val db: SqlDatabase)(implicit
|
||||
returnType = returnType,
|
||||
parentType = None,
|
||||
isStatic = false,
|
||||
documentation = None,
|
||||
documentation = doc,
|
||||
scopeStartLine = scope.start.line,
|
||||
scopeStartOffset = scope.start.character,
|
||||
scopeEndLine = scope.end.line,
|
||||
@ -1149,7 +1159,7 @@ final class SqlSuggestionsRepo(val db: SqlDatabase)(implicit
|
||||
reexport = None
|
||||
)
|
||||
row -> args
|
||||
case Suggestion.Local(expr, module, name, returnType, scope) =>
|
||||
case Suggestion.Local(expr, module, name, returnType, scope, doc, _, _) =>
|
||||
val row = SuggestionRow(
|
||||
id = None,
|
||||
externalIdLeast = expr.map(_.getLeastSignificantBits),
|
||||
@ -1161,7 +1171,7 @@ final class SqlSuggestionsRepo(val db: SqlDatabase)(implicit
|
||||
returnType = returnType,
|
||||
parentType = None,
|
||||
isStatic = false,
|
||||
documentation = None,
|
||||
documentation = doc,
|
||||
scopeStartLine = scope.start.line,
|
||||
scopeStartOffset = scope.start.character,
|
||||
scopeEndLine = scope.end.line,
|
||||
@ -1288,7 +1298,10 @@ final class SqlSuggestionsRepo(val db: SqlDatabase)(implicit
|
||||
suggestion.scopeEndLine,
|
||||
suggestion.scopeEndOffset
|
||||
)
|
||||
)
|
||||
),
|
||||
documentation = suggestion.documentation,
|
||||
documentationHtml = None,
|
||||
documentationSections = None
|
||||
)
|
||||
case SuggestionKind.LOCAL =>
|
||||
Suggestion.Local(
|
||||
@ -1306,7 +1319,10 @@ final class SqlSuggestionsRepo(val db: SqlDatabase)(implicit
|
||||
suggestion.scopeEndLine,
|
||||
suggestion.scopeEndOffset
|
||||
)
|
||||
)
|
||||
),
|
||||
documentation = suggestion.documentation,
|
||||
documentationHtml = None,
|
||||
documentationSections = None
|
||||
)
|
||||
case k =>
|
||||
throw new NoSuchElementException(s"Unknown suggestion kind: $k")
|
||||
|
@ -675,6 +675,73 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
)
|
||||
}
|
||||
|
||||
"update suggestion function documentation" taggedAs Retry in withRepo {
|
||||
repo =>
|
||||
val newDoc = "My awesome function!"
|
||||
val action = for {
|
||||
(v1, Seq(_, _, _, _, _, id1, _)) <- repo.insertAll(
|
||||
Seq(
|
||||
suggestion.module,
|
||||
suggestion.tpe,
|
||||
suggestion.constructor,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
)
|
||||
(v2, id2) <- repo.update(
|
||||
suggestion.function,
|
||||
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.function.copy(documentation = Some(newDoc))
|
||||
)
|
||||
}
|
||||
|
||||
"update suggestion local documentation" taggedAs Retry in withRepo { repo =>
|
||||
val newDoc = "Some stuff there"
|
||||
val action = for {
|
||||
(v1, Seq(_, _, _, _, _, _, id1)) <- repo.insertAll(
|
||||
Seq(
|
||||
suggestion.module,
|
||||
suggestion.tpe,
|
||||
suggestion.constructor,
|
||||
suggestion.method,
|
||||
suggestion.conversion,
|
||||
suggestion.function,
|
||||
suggestion.local
|
||||
)
|
||||
)
|
||||
(v2, id2) <- repo.update(
|
||||
suggestion.local,
|
||||
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.local.copy(documentation = Some(newDoc))
|
||||
)
|
||||
}
|
||||
|
||||
"update suggestion removing documentation" taggedAs Retry in withRepo {
|
||||
repo =>
|
||||
val action = for {
|
||||
@ -1898,8 +1965,9 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
Suggestion.Argument("x", "Number", false, true, Some("0"))
|
||||
),
|
||||
returnType = "local.Test.Main.MyType",
|
||||
scope =
|
||||
Suggestion.Scope(Suggestion.Position(1, 5), Suggestion.Position(6, 0))
|
||||
scope = Suggestion
|
||||
.Scope(Suggestion.Position(1, 5), Suggestion.Position(6, 0)),
|
||||
documentation = Some("My function bar.")
|
||||
)
|
||||
|
||||
val local: Suggestion.Local =
|
||||
@ -1911,7 +1979,8 @@ class SuggestionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
|
||||
scope = Suggestion.Scope(
|
||||
Suggestion.Position(3, 4),
|
||||
Suggestion.Position(6, 0)
|
||||
)
|
||||
),
|
||||
documentation = Some("Some bazz")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user