Skip to content

Commit

Permalink
Set suggestion reexports when serializing the library (#6778)
Browse files Browse the repository at this point in the history
close #6613

Changelog
- feat: during the library serialization, build the exports map and set the reexport field of the suggestion

# Important Notes
IDE does not create additional imports for re-exported symbols.

![2023-05-18-192739_2019x828_scrot](https://github.com/enso-org/enso/assets/357683/5ef20dfe-d6a5-4935-a759-4af10b0817a5)
  • Loading branch information
4e6 authored May 19, 2023
1 parent 029b900 commit 9ec7415
Show file tree
Hide file tree
Showing 9 changed files with 246 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,13 @@ class SuggestionsHandlerSpec
),
Vector()
),
Tree.Node(
Api.SuggestionUpdate(
Suggestions.tpe,
Api.SuggestionAction.Add()
),
Vector()
),
Tree.Node(
Api.SuggestionUpdate(
Suggestions.constructor,
Expand Down Expand Up @@ -598,7 +605,11 @@ class SuggestionsHandlerSpec
ExportedSymbol.Module(
Suggestions.module.module
),
ExportedSymbol.Atom(
ExportedSymbol.Type(
Suggestions.tpe.module,
Suggestions.tpe.name
),
ExportedSymbol.Constructor(
Suggestions.constructor.module,
Suggestions.constructor.name
),
Expand All @@ -618,7 +629,7 @@ class SuggestionsHandlerSpec
Tree.Root(Vector())
)

val updates2 = Seq(1L, 2L, 3L).map { id =>
val updates2 = Seq(1L, 2L, 3L, 4L).map { id =>
SearchProtocol.SuggestionsDatabaseUpdate.Modify(
id,
reexport = Some(fieldUpdate(exportUpdateAdd.exports.module))
Expand All @@ -642,7 +653,11 @@ class SuggestionsHandlerSpec
ExportedSymbol.Module(
Suggestions.module.module
),
ExportedSymbol.Atom(
ExportedSymbol.Type(
Suggestions.tpe.module,
Suggestions.tpe.name
),
ExportedSymbol.Constructor(
Suggestions.constructor.module,
Suggestions.constructor.name
),
Expand All @@ -662,7 +677,7 @@ class SuggestionsHandlerSpec
Tree.Root(Vector())
)

val updates3 = Seq(1L, 2L, 3L).map { id =>
val updates3 = Seq(1L, 2L, 3L, 4L).map { id =>
SearchProtocol.SuggestionsDatabaseUpdate.Modify(
id,
reexport = Some(fieldRemove)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -500,11 +500,14 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec {
ModuleExports(
"Foo.Bar",
ListSet(
ExportedSymbol
.Atom(
Suggestions.constructor.module,
Suggestions.constructor.name
)
ExportedSymbol.Type(
Suggestions.tpe.module,
Suggestions.tpe.name
),
ExportedSymbol.Constructor(
Suggestions.constructor.module,
Suggestions.constructor.name
)
)
),
Api.ExportsAction.Add()
Expand All @@ -519,6 +522,14 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec {
"method" : "search/suggestionsDatabaseUpdates",
"params" : {
"updates" : [
{
"type" : "Modify",
"id" : 1,
"reexport" : {
"tag" : "Set",
"value" : "Foo.Bar"
}
},
{
"type" : "Modify",
"id" : 2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ import com.fasterxml.jackson.annotation.{JsonSubTypes, JsonTypeInfo}
name = "exportedModule"
),
new JsonSubTypes.Type(
value = classOf[ExportedSymbol.Atom],
name = "exportedAtom"
value = classOf[ExportedSymbol.Type],
name = "exportedType"
),
new JsonSubTypes.Type(
value = classOf[ExportedSymbol.Constructor],
name = "exportedConstructor"
),
new JsonSubTypes.Type(
value = classOf[ExportedSymbol.Method],
Expand All @@ -28,26 +32,65 @@ sealed trait ExportedSymbol {
}
object ExportedSymbol {

/** Create [[ExportedSymbol]] from [[Suggestion]].
*
* @param suggestion the suggestion to convert
* @return the corresponding [[ExportedSymbol]]
*/
def fromSuggestion(suggestion: Suggestion): Option[ExportedSymbol] =
suggestion match {
case s: Suggestion.Module => Some(Module(s.module))
case s: Suggestion.Type => Some(Type(s.module, s.name))
case s: Suggestion.Constructor => Some(Constructor(s.module, s.name))
case s: Suggestion.Method => Some(Method(s.module, s.name))
case _: Suggestion.Conversion => None
case _: Suggestion.Function => None
case _: Suggestion.Local => None
}

/** Create an exported symbol of the suggestion module.
*
* @param suggestion the suggestion to convert
* @return the corresponding [[ExportedSymbol.Module]]
*/
def suggestionModule(suggestion: Suggestion): ExportedSymbol.Module =
ExportedSymbol.Module(suggestion.module)

/** The module symbol.
*
* @param module the module name
*/
case class Module(module: String) extends ExportedSymbol {

/** @inheritdoc */
override def name: String =
module

/** @inheritdoc */
override def kind: Suggestion.Kind =
Suggestion.Kind.Module
}

/** The atom symbol.
/** The type symbol.
*
* @param module the module defining this atom
* @param name the atom name
* @param name the type name
*/
case class Type(module: String, name: String) extends ExportedSymbol {

/** @inheritdoc */
override def kind: Suggestion.Kind =
Suggestion.Kind.Type
}

/** The constructor symbol.
*
* @param module the module where this constructor is defined
* @param name the constructor name
*/
case class Atom(module: String, name: String) extends ExportedSymbol {
case class Constructor(module: String, name: String) extends ExportedSymbol {

/** @inheritdoc */
override def kind: Suggestion.Kind =
Suggestion.Kind.Constructor
}
Expand All @@ -59,6 +102,7 @@ object ExportedSymbol {
*/
case class Method(module: String, name: String) extends ExportedSymbol {

/** @inheritdoc */
override def kind: Suggestion.Kind =
Suggestion.Kind.Method
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ sealed trait Suggestion extends ToLogString {
def name: String
def returnType: String
def documentation: Option[String]

/** Set the reexport field of the suggestion. */
def withReexport(reexport: Option[String]): Suggestion
}

object Suggestion {
Expand Down Expand Up @@ -220,6 +223,10 @@ object Suggestion {
override def returnType: String =
module

/** @inheritdoc */
override def withReexport(reexport: Option[String]): Module =
copy(reexport = reexport)

/** @inheritdoc */
override def toLogString(shouldMask: Boolean): String =
s"Module(module=$module,name=$name,documentation=" +
Expand Down Expand Up @@ -250,6 +257,10 @@ object Suggestion {
) extends Suggestion
with ToLogString {

/** @inheritdoc */
override def withReexport(reexport: Option[String]): Type =
copy(reexport = reexport)

/** @inheritdoc */
override def toLogString(shouldMask: Boolean): String =
"Type(" +
Expand Down Expand Up @@ -285,6 +296,10 @@ object Suggestion {
) extends Suggestion
with ToLogString {

/** @inheritdoc */
override def withReexport(reexport: Option[String]): Constructor =
copy(reexport = reexport)

/** @inheritdoc */
override def toLogString(shouldMask: Boolean): String =
"Constructor(" +
Expand Down Expand Up @@ -323,6 +338,10 @@ object Suggestion {
) extends Suggestion
with ToLogString {

/** @inheritdoc */
override def withReexport(reexport: Option[String]): Method =
copy(reexport = reexport)

/** @inheritdoc */
override def toLogString(shouldMask: Boolean): String =
"Method(" +
Expand Down Expand Up @@ -357,6 +376,10 @@ object Suggestion {
reexport: Option[String] = None
) extends Suggestion {

/** @inheritdoc */
override def withReexport(reexport: Option[String]): Conversion =
copy(reexport = reexport)

/** @inheritdoc */
override def name: String =
Kind.Conversion.From
Expand Down Expand Up @@ -394,6 +417,10 @@ object Suggestion {
) extends Suggestion
with ToLogString {

/** @inheritdoc */
override def withReexport(reexport: Option[String]): Function =
this

/** @inheritdoc */
override def toLogString(shouldMask: Boolean): String =
"Function(" +
Expand Down Expand Up @@ -425,6 +452,10 @@ object Suggestion {
documentation: Option[String]
) extends Suggestion {

/** @inheritdoc */
override def withReexport(reexport: Option[String]): Local =
this

/** @inheritdoc */
override def toLogString(shouldMask: Boolean): String =
s"Local(" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1014,7 +1014,7 @@ class RuntimeSuggestionUpdatesTest
)
)
context.receiveNIgnoreExpressionUpdates(
5
6
) should contain theSameElementsAs Seq(
Api.Response(Api.BackgroundJobsStartedNotification()),
Api.Response(requestId, Api.PushContextResponse(contextId)),
Expand Down Expand Up @@ -1151,7 +1151,8 @@ class RuntimeSuggestionUpdatesTest
ModuleExports(
"Enso_Test.Test.Main",
Set(
ExportedSymbol.Atom("Enso_Test.Test.A", "MkA"),
ExportedSymbol.Type("Enso_Test.Test.A", "MyType"),
ExportedSymbol.Constructor("Enso_Test.Test.A", "MkA"),
ExportedSymbol.Method("Enso_Test.Test.A", "hello")
)
),
Expand Down Expand Up @@ -1190,6 +1191,7 @@ class RuntimeSuggestionUpdatesTest
)
)
),
Api.Response(Api.AnalyzeModuleInScopeJobFinished()),
context.executionComplete(contextId)
)
context.consumeOut shouldEqual List("Hello World!")
Expand All @@ -1210,7 +1212,7 @@ class RuntimeSuggestionUpdatesTest
)
)
context.receiveNIgnoreExpressionUpdates(
3
2
) should contain theSameElementsAs Seq(
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
Expand All @@ -1228,7 +1230,6 @@ class RuntimeSuggestionUpdatesTest
updates = Tree.Root(Vector())
)
),
Api.Response(Api.AnalyzeModuleInScopeJobFinished()),
context.executionComplete(contextId)
)
context.consumeOut shouldEqual List("Hello World!")
Expand Down Expand Up @@ -1259,7 +1260,10 @@ class RuntimeSuggestionUpdatesTest
Api.ExportsUpdate(
ModuleExports(
"Enso_Test.Test.Main",
Set(ExportedSymbol.Atom("Enso_Test.Test.A", "MkA"))
Set(
ExportedSymbol.Type("Enso_Test.Test.A", "MyType"),
ExportedSymbol.Constructor("Enso_Test.Test.A", "MkA")
)
),
Api.ExportsAction.Remove()
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package org.enso.compiler.context;

import org.enso.pkg.QualifiedName;
import org.enso.polyglot.ExportedSymbol;
import org.enso.polyglot.ModuleExports;
import org.enso.polyglot.Suggestion;
import scala.Option;
import scala.runtime.BoxedUnit;

import java.util.HashMap;
import java.util.Map;

public final class ExportsMap {

private static final String MODULE_MAIN = "Main";
private static final String TYPE_SUFFIX = "type";

private final Map<ExportedSymbol, QualifiedName> exportsMap;

public ExportsMap() {
this.exportsMap = new HashMap<>();
}

public ExportsMap(Map<ExportedSymbol, QualifiedName> exportsMap) {
this.exportsMap = exportsMap;
}

public void add(ExportedSymbol symbol, QualifiedName moduleName) {
exportsMap.merge(symbol, moduleName, ExportsMap::getShortest);
}

public void addAll(QualifiedName moduleName, ModuleExports moduleExports) {
moduleExports
.symbols()
.foreach(
symbol -> {
add(symbol, moduleName);
return BoxedUnit.UNIT;
});
}

public QualifiedName get(ExportedSymbol symbol) {
return exportsMap.get(symbol);
}

public QualifiedName get(Suggestion suggestion) {
return ExportedSymbol.fromSuggestion(suggestion)
.flatMap(symbol -> Option.apply(exportsMap.get(symbol)))
.getOrElse(() -> exportsMap.get(ExportedSymbol.suggestionModule(suggestion)));
}

private static QualifiedName getShortest(QualifiedName name1, QualifiedName name2) {
return length(name1) <= length(name2) ? name1 : name2;
}

private static int length(QualifiedName qualifiedName) {
QualifiedName name =
qualifiedName.item().equals(TYPE_SUFFIX) ? qualifiedName.getParent().get() : qualifiedName;
return name.item().equals(MODULE_MAIN) ? name.path().length() : name.path().length() + 1;
}
}
Loading

0 comments on commit 9ec7415

Please sign in to comment.