mirror of
https://github.com/enso-org/enso.git
synced 2024-11-23 08:08:34 +03:00
Use autoscoping when constructing tag values of suggestion arguments (#9293)
This commit is contained in:
parent
8aef2146db
commit
1c4a927701
@ -1,7 +1,6 @@
|
||||
package org.enso.compiler.context
|
||||
|
||||
import org.enso.compiler.Compiler
|
||||
import org.enso.compiler.context.CompilerContext
|
||||
import org.enso.compiler.core.Implicits.AsMetadata
|
||||
import org.enso.compiler.core.{ExternalID, IR}
|
||||
import org.enso.compiler.core.ir.expression.{Application, Operator}
|
||||
@ -640,25 +639,42 @@ final class SuggestionBuilder[A: IndexedSource](
|
||||
isSuspended = varg.suspended,
|
||||
hasDefault = varg.defaultValue.isDefined,
|
||||
defaultValue = varg.defaultValue.map(buildDefaultValue),
|
||||
tagValues = buildTagValues(targ)
|
||||
tagValues = buildTagValues(targ, varg.ascribedType.nonEmpty)
|
||||
)
|
||||
|
||||
/** Build tag values of type argument.
|
||||
*
|
||||
* @param targ the type argument
|
||||
* @param hasTypeAscription if the type ascription was used in type definition
|
||||
* @return the list of tag values
|
||||
*/
|
||||
private def buildTagValues(targ: TypeArg): Option[Seq[String]] = {
|
||||
def go(arg: TypeArg): Seq[String] = arg match {
|
||||
case TypeArg.Sum(_, List()) => Seq()
|
||||
case TypeArg.Sum(_, variants) => variants.flatMap(go)
|
||||
case TypeArg.Value(n) => Seq(n.toString)
|
||||
case _ => Seq()
|
||||
private def buildTagValues(
|
||||
targ: TypeArg,
|
||||
hasTypeAscription: Boolean
|
||||
): Option[Seq[String]] = {
|
||||
def mkUnqualified(name: QualifiedName): String =
|
||||
name.item
|
||||
def mkQualified(name: QualifiedName): String =
|
||||
name.toString
|
||||
def mkAutoScopeCall(name: String): String =
|
||||
s"..$name"
|
||||
def go(arg: TypeArg, useAutoScope: Boolean): Seq[String] = arg match {
|
||||
case TypeArg.Sum(_, List()) => Seq()
|
||||
case TypeArg.Sum(_, variants) =>
|
||||
variants.flatMap(go(_, useAutoScope))
|
||||
case TypeArg.Value(n) =>
|
||||
Seq(if (useAutoScope) mkUnqualified(n) else mkQualified(n))
|
||||
case _ => Seq()
|
||||
}
|
||||
|
||||
targ match {
|
||||
case s: TypeArg.Sum =>
|
||||
val tagValues = go(s)
|
||||
val tagItems = go(s, hasTypeAscription)
|
||||
val canUseAutoScope =
|
||||
hasTypeAscription && tagItems.distinct.length == tagItems.length
|
||||
val tagValues =
|
||||
if (canUseAutoScope) tagItems.map(mkAutoScopeCall)
|
||||
else go(s, useAutoScope = false)
|
||||
Option.unless(tagValues.isEmpty)(tagValues)
|
||||
case _ => None
|
||||
|
||||
|
@ -774,7 +774,7 @@ class SuggestionBuilderTest extends AnyWordSpecLike with Matchers {
|
||||
|
|
||||
|type Auto
|
||||
|
|
||||
|foo : Text | Boolean | Value | Auto -> Any
|
||||
|foo : Text | Boolean | Value | Auto -> Value
|
||||
|foo a = a
|
||||
|""".stripMargin
|
||||
val module = code.preprocessModule
|
||||
@ -854,7 +854,314 @@ class SuggestionBuilderTest extends AnyWordSpecLike with Matchers {
|
||||
)
|
||||
),
|
||||
selfType = "Unnamed.Test",
|
||||
returnType = "Any",
|
||||
returnType = "Unnamed.Test.Value",
|
||||
isStatic = true,
|
||||
documentation = None,
|
||||
annotations = Seq()
|
||||
),
|
||||
Vector()
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
"build argument tag values from ascribed type" in {
|
||||
|
||||
val code =
|
||||
"""type Value
|
||||
| A
|
||||
| B
|
||||
|
|
||||
|type Auto
|
||||
|
|
||||
|foo (a : Value | Auto) = a
|
||||
|""".stripMargin
|
||||
val module = code.preprocessModule
|
||||
|
||||
build(code, module) shouldEqual Tree.Root(
|
||||
Vector(
|
||||
ModuleNode,
|
||||
Tree.Node(
|
||||
Suggestion.Type(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "Value",
|
||||
params = Seq(),
|
||||
returnType = "Unnamed.Test.Value",
|
||||
parentType = Some(SuggestionBuilder.Any),
|
||||
documentation = None
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
Tree.Node(
|
||||
Suggestion.Constructor(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "A",
|
||||
arguments = Seq(),
|
||||
returnType = "Unnamed.Test.Value",
|
||||
documentation = None,
|
||||
annotations = Seq()
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
Tree.Node(
|
||||
Suggestion.Constructor(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "B",
|
||||
arguments = Seq(),
|
||||
returnType = "Unnamed.Test.Value",
|
||||
documentation = None,
|
||||
annotations = Seq()
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
Tree.Node(
|
||||
Suggestion.Type(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "Auto",
|
||||
params = Seq(),
|
||||
returnType = "Unnamed.Test.Auto",
|
||||
parentType = Some(SuggestionBuilder.Any),
|
||||
documentation = None
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
Tree.Node(
|
||||
Suggestion.DefinedMethod(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "foo",
|
||||
arguments = Seq(
|
||||
Suggestion.Argument(
|
||||
"a",
|
||||
"Unnamed.Test.Value | Unnamed.Test.Auto",
|
||||
false,
|
||||
false,
|
||||
None,
|
||||
Some(Seq("..A", "..B", "..Auto"))
|
||||
)
|
||||
),
|
||||
selfType = "Unnamed.Test",
|
||||
returnType = SuggestionBuilder.Any,
|
||||
isStatic = true,
|
||||
documentation = None,
|
||||
annotations = Seq()
|
||||
),
|
||||
Vector()
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
"build argument tag values from ascribed type and type signature" in {
|
||||
|
||||
val code =
|
||||
"""type Value
|
||||
| A
|
||||
| B
|
||||
|
|
||||
|type Auto
|
||||
|
|
||||
|foo : Value | Auto -> Value | Auto
|
||||
|foo (a : Value | Auto) = a
|
||||
|""".stripMargin
|
||||
val module = code.preprocessModule
|
||||
|
||||
build(code, module) shouldEqual Tree.Root(
|
||||
Vector(
|
||||
ModuleNode,
|
||||
Tree.Node(
|
||||
Suggestion.Type(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "Value",
|
||||
params = Seq(),
|
||||
returnType = "Unnamed.Test.Value",
|
||||
parentType = Some(SuggestionBuilder.Any),
|
||||
documentation = None
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
Tree.Node(
|
||||
Suggestion.Constructor(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "A",
|
||||
arguments = Seq(),
|
||||
returnType = "Unnamed.Test.Value",
|
||||
documentation = None,
|
||||
annotations = Seq()
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
Tree.Node(
|
||||
Suggestion.Constructor(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "B",
|
||||
arguments = Seq(),
|
||||
returnType = "Unnamed.Test.Value",
|
||||
documentation = None,
|
||||
annotations = Seq()
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
Tree.Node(
|
||||
Suggestion.Type(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "Auto",
|
||||
params = Seq(),
|
||||
returnType = "Unnamed.Test.Auto",
|
||||
parentType = Some(SuggestionBuilder.Any),
|
||||
documentation = None
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
Tree.Node(
|
||||
Suggestion.DefinedMethod(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "foo",
|
||||
arguments = Seq(
|
||||
Suggestion.Argument(
|
||||
"a",
|
||||
"Unnamed.Test.Value | Unnamed.Test.Auto",
|
||||
false,
|
||||
false,
|
||||
None,
|
||||
Some(Seq("..A", "..B", "..Auto"))
|
||||
)
|
||||
),
|
||||
selfType = "Unnamed.Test",
|
||||
returnType = "Unnamed.Test.Value | Unnamed.Test.Auto",
|
||||
isStatic = true,
|
||||
documentation = None,
|
||||
annotations = Seq()
|
||||
),
|
||||
Vector()
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
"build argument tag values checking if autoscoped constructors are distinct" in {
|
||||
|
||||
val code =
|
||||
"""type T
|
||||
| A
|
||||
| B
|
||||
|
|
||||
|type K
|
||||
| B
|
||||
| C
|
||||
|
|
||||
|foo (a : T | K) = a
|
||||
|""".stripMargin
|
||||
val module = code.preprocessModule
|
||||
|
||||
build(code, module) shouldEqual Tree.Root(
|
||||
Vector(
|
||||
ModuleNode,
|
||||
Tree.Node(
|
||||
Suggestion.Type(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "T",
|
||||
params = Seq(),
|
||||
returnType = "Unnamed.Test.T",
|
||||
parentType = Some(SuggestionBuilder.Any),
|
||||
documentation = None
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
Tree.Node(
|
||||
Suggestion.Constructor(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "A",
|
||||
arguments = Seq(),
|
||||
returnType = "Unnamed.Test.T",
|
||||
documentation = None,
|
||||
annotations = Seq()
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
Tree.Node(
|
||||
Suggestion.Constructor(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "B",
|
||||
arguments = Seq(),
|
||||
returnType = "Unnamed.Test.T",
|
||||
documentation = None,
|
||||
annotations = Seq()
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
Tree.Node(
|
||||
Suggestion.Type(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "K",
|
||||
params = Seq(),
|
||||
returnType = "Unnamed.Test.K",
|
||||
parentType = Some(SuggestionBuilder.Any),
|
||||
documentation = None
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
Tree.Node(
|
||||
Suggestion.Constructor(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "B",
|
||||
arguments = Seq(),
|
||||
returnType = "Unnamed.Test.K",
|
||||
documentation = None,
|
||||
annotations = Seq()
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
Tree.Node(
|
||||
Suggestion.Constructor(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "C",
|
||||
arguments = Seq(),
|
||||
returnType = "Unnamed.Test.K",
|
||||
documentation = None,
|
||||
annotations = Seq()
|
||||
),
|
||||
Vector()
|
||||
),
|
||||
Tree.Node(
|
||||
Suggestion.DefinedMethod(
|
||||
externalId = None,
|
||||
module = "Unnamed.Test",
|
||||
name = "foo",
|
||||
arguments = Seq(
|
||||
Suggestion.Argument(
|
||||
"a",
|
||||
"Unnamed.Test.T | Unnamed.Test.K",
|
||||
false,
|
||||
false,
|
||||
None,
|
||||
Some(
|
||||
Seq(
|
||||
"Unnamed.Test.T.A",
|
||||
"Unnamed.Test.T.B",
|
||||
"Unnamed.Test.K.B",
|
||||
"Unnamed.Test.K.C"
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
selfType = "Unnamed.Test",
|
||||
returnType = SuggestionBuilder.Any,
|
||||
isStatic = true,
|
||||
documentation = None,
|
||||
annotations = Seq()
|
||||
@ -1230,8 +1537,8 @@ class SuggestionBuilderTest extends AnyWordSpecLike with Matchers {
|
||||
Some("Boolean.True"),
|
||||
Some(
|
||||
List(
|
||||
"Standard.Base.Data.Boolean.Boolean.True",
|
||||
"Standard.Base.Data.Boolean.Boolean.False"
|
||||
"..True",
|
||||
"..False"
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -2333,7 +2640,7 @@ class SuggestionBuilderTest extends AnyWordSpecLike with Matchers {
|
||||
false,
|
||||
false,
|
||||
None,
|
||||
Some(Seq("Unnamed.Test.S.X", "Unnamed.Test.S.Y"))
|
||||
Some(Seq("..X", "..Y"))
|
||||
)
|
||||
),
|
||||
returnType = "Unnamed.Test.T",
|
||||
|
Loading…
Reference in New Issue
Block a user