diff --git a/CHANGELOG.md b/CHANGELOG.md index d802f4185a18..f3ebc9300aca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -188,6 +188,7 @@ - [Fixed execution of defaulted arguments of Atom Constructors][3358] - [Converting Enso Date to java.time.LocalDate and back][3374] - [Functions with all-defaulted arguments now execute automatically][3414] +- [Provide `tagValues` for function arguments in the language server][3422] - [Delay construction of Truffle nodes to speed initialization][3429] - [Frgaal compiler integration to allow for latest Java constructs][3421] @@ -202,6 +203,7 @@ [3412]: https://github.com/enso-org/enso/pull/3412 [3414]: https://github.com/enso-org/enso/pull/3414 [3417]: https://github.com/enso-org/enso/pull/3417 +[3422]: https://github.com/enso-org/enso/pull/3422 [3429]: https://github.com/enso-org/enso/pull/3429 [3421]: https://github.com/enso-org/enso/pull/3421 diff --git a/engine/language-server/src/test/scala/org/enso/languageserver/websocket/json/SuggestionsHandlerEventsTest.scala b/engine/language-server/src/test/scala/org/enso/languageserver/websocket/json/SuggestionsHandlerEventsTest.scala index 821a869c7b75..3cc4bcfb4b9f 100644 --- a/engine/language-server/src/test/scala/org/enso/languageserver/websocket/json/SuggestionsHandlerEventsTest.scala +++ b/engine/language-server/src/test/scala/org/enso/languageserver/websocket/json/SuggestionsHandlerEventsTest.scala @@ -58,7 +58,8 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec { "reprType" : "Any", "isSuspended" : false, "hasDefault" : false, - "defaultValue" : null + "defaultValue" : null, + "tagValues" : null } ], "returnType" : "MyAtom", @@ -141,14 +142,16 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec { "reprType" : "MyType", "isSuspended" : false, "hasDefault" : false, - "defaultValue" : null + "defaultValue" : null, + "tagValues" : null }, { "name" : "foo", "reprType" : "Number", "isSuspended" : false, "hasDefault" : true, - "defaultValue" : "42" + "defaultValue" : "42", + "tagValues" : null } ], "selfType" : "MyType", @@ -224,21 +227,24 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec { "reprType" : "Any", "isSuspended" : false, "hasDefault" : false, - "defaultValue" : null + "defaultValue" : null, + "tagValues" : null }, { "name" : "b", "reprType" : "Any", "isSuspended" : true, "hasDefault" : false, - "defaultValue" : null + "defaultValue" : null, + "tagValues" : null }, { "name" : "c", "reprType" : "Any", "isSuspended" : false, "hasDefault" : true, - "defaultValue" : "C" + "defaultValue" : "C", + "tagValues" : null } ], "returnType" : "IO", @@ -356,21 +362,24 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec { "reprType" : "Any", "isSuspended" : false, "hasDefault" : false, - "defaultValue" : null + "defaultValue" : null, + "tagValues" : null }, { "name" : "b", "reprType" : "Any", "isSuspended" : true, "hasDefault" : false, - "defaultValue" : null + "defaultValue" : null, + "tagValues" : null }, { "name" : "c", "reprType" : "Any", "isSuspended" : false, "hasDefault" : true, - "defaultValue" : "C" + "defaultValue" : "C", + "tagValues" : null } ], "returnType" : "IO", @@ -398,7 +407,8 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec { "reprType" : "Any", "isSuspended" : false, "hasDefault" : false, - "defaultValue" : null + "defaultValue" : null, + "tagValues" : null } ], "returnType" : "MyAtom", @@ -461,14 +471,16 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec { "reprType" : "MyType", "isSuspended" : false, "hasDefault" : false, - "defaultValue" : null + "defaultValue" : null, + "tagValues" : null }, { "name" : "foo", "reprType" : "Number", "isSuspended" : false, "hasDefault" : true, - "defaultValue" : "42" + "defaultValue" : "42", + "tagValues" : null } ], "selfType" : "MyType", @@ -572,7 +584,8 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec { "reprType" : "Any", "isSuspended" : true, "hasDefault" : false, - "defaultValue" : null + "defaultValue" : null, + "tagValues" : null } } ] diff --git a/engine/polyglot-api/src/main/scala/org/enso/polyglot/Suggestion.scala b/engine/polyglot-api/src/main/scala/org/enso/polyglot/Suggestion.scala index 0d4b1cd6b216..820cb8613d18 100644 --- a/engine/polyglot-api/src/main/scala/org/enso/polyglot/Suggestion.scala +++ b/engine/polyglot-api/src/main/scala/org/enso/polyglot/Suggestion.scala @@ -123,7 +123,8 @@ object Suggestion { reprType: String, isSuspended: Boolean, hasDefault: Boolean, - defaultValue: Option[String] + defaultValue: Option[String], + tagValues: Option[Seq[String]] = None ) extends ToLogString { /** @inheritdoc */ diff --git a/engine/polyglot-api/src/main/scala/org/enso/polyglot/data/Tree.scala b/engine/polyglot-api/src/main/scala/org/enso/polyglot/data/Tree.scala index 9ede2f50c5e5..a000aa5bccac 100644 --- a/engine/polyglot-api/src/main/scala/org/enso/polyglot/data/Tree.scala +++ b/engine/polyglot-api/src/main/scala/org/enso/polyglot/data/Tree.scala @@ -30,6 +30,16 @@ sealed trait Tree[+A] { final def map[B](f: A => B): Tree[B] = Tree.map(this)(f) + /** Finds the first element of the tree for which the given partial function + * is defined, and applies the partial function to it. + * + * @param f the partial function to apply + * @return the result of running `f` on the first element it's defined for. + */ + @JsonIgnore + final def collectFirst[B](f: PartialFunction[A, B]): Option[B] = + Tree.collectFirst(this)(f) + /** Selects all elements which satisfy a predicate. * * @param p the predicate used to test elements @@ -208,6 +218,22 @@ object Tree { Node(f(a), cx.map(mapNode(_)(f))) } + private def collectFirst[A, B]( + tree: Tree[A] + )(f: PartialFunction[A, B]): Option[B] = { + def collectFirstNode(node: Tree.Node[A]): Option[B] = { + if (f.isDefinedAt(node.element)) { + Some(f(node.element)) + } else { + node.children.collectFirst((collectFirstNode _).unlift) + } + } + tree match { + case Root(c) => c.collectFirst((collectFirstNode _).unlift) + case n: Node[A] => collectFirstNode(n) + } + } + private def filter[A](tree: Tree[A])(p: A => Boolean): Tree[A] = { def filterNode(node: Tree.Node[A]): Option[Tree.Node[A]] = { val childrenFiltered = node.children.flatMap(filterNode) diff --git a/engine/runtime/src/main/scala/org/enso/compiler/codegen/RuntimeStubsGenerator.scala b/engine/runtime/src/main/scala/org/enso/compiler/codegen/RuntimeStubsGenerator.scala index aba013947586..b246761acd59 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/codegen/RuntimeStubsGenerator.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/codegen/RuntimeStubsGenerator.scala @@ -21,7 +21,7 @@ class RuntimeStubsGenerator() { BindingAnalysis, "Non-parsed module used in stubs generator" ) - localBindings.types.foreach { tp => + localBindings.constructors.foreach { tp => val constructor = new AtomConstructor(tp.name, scope) scope.registerConstructor(constructor) } diff --git a/engine/runtime/src/main/scala/org/enso/compiler/context/SuggestionBuilder.scala b/engine/runtime/src/main/scala/org/enso/compiler/context/SuggestionBuilder.scala index ac2ca8a2b009..6319ab319853 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/context/SuggestionBuilder.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/context/SuggestionBuilder.scala @@ -336,13 +336,22 @@ final class SuggestionBuilder[A: IndexedSource](val source: A) { resolvedName match { case BindingsMap.ResolvedModule(module) => Some(module.getName) - case BindingsMap.ResolvedConstructor(module, cons) => - Some(module.getName.createChild(cons.name)) + case cons: BindingsMap.ResolvedConstructor => + Some(cons.qualifiedName) case _ => None } } + private def buildResolvedUnionTypeName( + resolvedName: BindingsMap.ResolvedTypeName + ): Option[TypeArg] = resolvedName match { + case tp: BindingsMap.ResolvedType => + Some(TypeArg.Sum(tp.qualifiedName, tp.getVariants.map(_.qualifiedName))) + case other: BindingsMap.ResolvedName => + buildResolvedTypeName(other).map(TypeArg.Value) + } + /** Build type signature from the ir metadata. * * @param typeSignature the type signature metadata @@ -380,9 +389,8 @@ final class SuggestionBuilder[A: IndexedSource](val source: A) { args :++ arg case IR.Function.Lambda(List(targ), body, _, _, _, _) => val typeName = targ.name.name - val qualifiedTypeName = resolveTypeName(bindings, typeName) - .getOrElse(QualifiedName.simpleName(typeName)) - val tdef = TypeArg.Value(qualifiedTypeName) + val tdef = resolveTypeName(bindings, typeName) + .getOrElse(TypeArg.Value(QualifiedName.simpleName(typeName))) go(body, args :+ tdef) case IR.Application.Prefix(tfun, targs, _, _, _, _) => val appFunction = go(tfun, Vector()).head @@ -390,9 +398,9 @@ final class SuggestionBuilder[A: IndexedSource](val source: A) { args :+ TypeArg.Application(appFunction, appArgs.toVector) case tname: IR.Name => val typeName = tname.name - val qualifiedTypeName = resolveTypeName(bindings, typeName) - .getOrElse(QualifiedName.simpleName(typeName)) - args :+ TypeArg.Value(qualifiedTypeName) + val tdef = resolveTypeName(bindings, typeName) + .getOrElse(TypeArg.Value(QualifiedName.simpleName(typeName))) + args :+ tdef case _ => args } @@ -415,10 +423,10 @@ final class SuggestionBuilder[A: IndexedSource](val source: A) { private def resolveTypeName( bindings: Option[BindingAnalysis.Metadata], name: String - ): Option[QualifiedName] = { + ): Option[TypeArg] = { bindings - .flatMap(_.resolveUppercaseName(name).toOption) - .flatMap(buildResolvedTypeName) + .flatMap(_.resolveTypeName(name).toOption) + .flatMap(buildResolvedUnionTypeName) } /** Build arguments of a method. @@ -521,7 +529,11 @@ final class SuggestionBuilder[A: IndexedSource](val source: A) { reprType = buildTypeArgumentName(targ), isSuspended = varg.suspended, hasDefault = varg.defaultValue.isDefined, - defaultValue = varg.defaultValue.flatMap(buildDefaultValue) + defaultValue = varg.defaultValue.flatMap(buildDefaultValue), + tagValues = targ match { + case TypeArg.Sum(_, variants) => Some(variants.map(_.toString)) + case _ => None + } ) /** Build the name of type argument. @@ -549,6 +561,7 @@ final class SuggestionBuilder[A: IndexedSource](val source: A) { val argsList = args.map(go(_, level + 1)).mkString(" ") val typeName = s"$funText $argsList" if (level > 0) s"($typeName)" else typeName + case TypeArg.Sum(n, _) => n.toString } go(targ, 0) @@ -639,6 +652,13 @@ object SuggestionBuilder { sealed private trait TypeArg private object TypeArg { + /** A sum type – one of many possible options. + * @param name the qualified name of the type. + * @param variants the qualified names of constituent atoms. + */ + case class Sum(name: QualifiedName, variants: Seq[QualifiedName]) + extends TypeArg + /** Type with the name, like `A`. * * @param name the name of the type diff --git a/engine/runtime/src/main/scala/org/enso/compiler/core/IR.scala b/engine/runtime/src/main/scala/org/enso/compiler/core/IR.scala index 4268258785dd..c4468797dd43 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/core/IR.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/core/IR.scala @@ -937,6 +937,105 @@ object IR { } object Definition { + /** The definition of a union type and its members. + * + * NB: this should probably be removed once we propagate the union + * types logic through the runtime and implement statics – the whole + * notion of desugaring complex type definitions becomes obsolete then. + * + * @param name the name of the union + * @param members the members of this union + * @param location the source location that the node corresponds to + * @param passData the pass metadata associated with this node + * @param diagnostics compiler diagnostics for this node + */ + sealed case class UnionType( + name: IR.Name, + members: List[IR.Name], + override val location: Option[IdentifiedLocation], + override val passData: MetadataStorage = MetadataStorage(), + override val diagnostics: DiagnosticStorage = DiagnosticStorage() + ) extends Definition + with IRKind.Primitive { + override protected var id: Identifier = randomId + + def copy( + name: IR.Name = name, + members: List[IR.Name] = members, + location: Option[IdentifiedLocation] = location, + passData: MetadataStorage = passData, + diagnostics: DiagnosticStorage = diagnostics, + id: Identifier = id + ): UnionType = { + val res = UnionType(name, members, location, passData, diagnostics) + res.id = id + res + } + + /** @inheritdoc */ + override def duplicate( + keepLocations: Boolean = true, + keepMetadata: Boolean = true, + keepDiagnostics: Boolean = true, + keepIdentifiers: Boolean = false + ): UnionType = + copy( + name = name.duplicate( + keepLocations, + keepMetadata, + keepDiagnostics, + keepIdentifiers + ), + members = members.map( + _.duplicate( + keepLocations, + keepMetadata, + keepDiagnostics, + keepIdentifiers + ) + ), + location = if (keepLocations) location else None, + passData = + if (keepMetadata) passData.duplicate else MetadataStorage(), + diagnostics = + if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(), + id = if (keepIdentifiers) id else randomId + ) + + /** @inheritdoc */ + override def setLocation( + location: Option[IdentifiedLocation] + ): UnionType = + copy(location = location) + + /** @inheritdoc */ + override def mapExpressions(fn: Expression => Expression): UnionType = + this + + /** @inheritdoc */ + override def toString: String = + s""" + |IR.Module.Scope.Definition.UnionType( + |name = $name, + |members = $members, + |location = $location, + |passData = ${this.showPassData}, + |diagnostics = $diagnostics, + |id = $id + |) + |""".toSingleLine + + /** @inheritdoc */ + override def children: List[IR] = name :: members + + /** @inheritdoc */ + override def showCode(indent: Int): String = { + val fields = members.map(_.showCode(indent)).mkString(" | ") + + s"type ${name.showCode(indent)} = $fields" + } + } + /** The definition of an atom constructor and its associated arguments. * * @param name the name of the atom diff --git a/engine/runtime/src/main/scala/org/enso/compiler/data/BindingsMap.scala b/engine/runtime/src/main/scala/org/enso/compiler/data/BindingsMap.scala index f3b0093bfc26..93cb924f2e96 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/data/BindingsMap.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/data/BindingsMap.scala @@ -16,13 +16,14 @@ import scala.annotation.unused /** A utility structure for resolving symbols in a given module. * - * @param types the types defined in the current module + * @param constructors the types defined in the current module * @param polyglotSymbols the polyglot symbols imported into the scope * @param moduleMethods the methods defined with current module as `this` * @param currentModule the module holding these bindings */ case class BindingsMap( - types: List[BindingsMap.Cons], + types: List[BindingsMap.Type], + constructors: List[BindingsMap.Cons], polyglotSymbols: List[BindingsMap.PolyglotSymbol], moduleMethods: List[BindingsMap.ModuleMethod], currentModule: ModuleReference @@ -130,7 +131,7 @@ case class BindingsMap( private def findConstructorCandidates( name: String ): List[ResolvedConstructor] = { - types + constructors .filter(_.name == name) .map(ResolvedConstructor(currentModule, _)) } @@ -201,17 +202,19 @@ case class BindingsMap( } } - private def getBindingsFrom(module: ModuleReference): BindingsMap = { - module match { - case ModuleReference.Concrete(module) => - module.getIr.unsafeGetMetadata( - BindingAnalysis, - "imported module has no binding map info" - ) - case ModuleReference.Abstract(_) => - throw new CompilerError( - "Bindings cannot be obtained from an abstract module reference." - ) + /** Resolves a name as a type. + * + * NB: This should be removed when sum types become proper runtime values. + * + * @param name the type name to resolve. + * @return the resolution + */ + def resolveTypeName( + name: String + ): Either[ResolutionError, ResolvedTypeName] = { + types.find(_.name == name) match { + case Some(value) => Right(ResolvedType(currentModule, value)) + case None => resolveUppercaseName(name) } } @@ -336,6 +339,20 @@ case class BindingsMap( object BindingsMap { + private def getBindingsFrom(module: ModuleReference): BindingsMap = { + module match { + case ModuleReference.Concrete(module) => + module.getIr.unsafeGetMetadata( + BindingAnalysis, + "imported module has no binding map info" + ) + case ModuleReference.Abstract(_) => + throw new CompilerError( + "Bindings cannot be obtained from an abstract module reference." + ) + } + } + /** Utilities for methods automatically generated by the compiler. */ object Generated { @@ -721,6 +738,13 @@ object BindingsMap { */ case class Cons(name: String, arity: Int, allFieldsDefaulted: Boolean) + /** A representation of a sum type + * + * @param name the type name + * @param members the member names + */ + case class Type(name: String, members: Seq[String]) + /** A representation of an imported polyglot symbol. * * @param name the name of the symbol. @@ -733,23 +757,75 @@ object BindingsMap { */ case class ModuleMethod(name: String) - /** A result of successful name resolution. + /** Represents a resolved name on typelevel. + * + * NB: should be unified with `ResolvedName` and removed, once sum types get + * a proper runtime meaning. */ - sealed trait ResolvedName { + sealed trait ResolvedTypeName { def module: ModuleReference /** Convert the resolved name to abstract form. * * @return `this`, converted to abstract form */ - def toAbstract: ResolvedName + def toAbstract: ResolvedTypeName /** Convert the resolved name to concrete form. * * @param moduleMap the mapping from qualified names to modules * @return `this`, converted to concrete form */ - def toConcrete(moduleMap: ModuleMap): Option[ResolvedName] + def toConcrete(moduleMap: ModuleMap): Option[ResolvedTypeName] + } + + /** A name resolved to a sum type. + * + * @param module the module defining the type + * @param tp a representation for the type + */ + case class ResolvedType(override val module: ModuleReference, tp: Type) + extends ResolvedTypeName { + def getVariants: Seq[ResolvedConstructor] = { + val bindingsMap = getBindingsFrom(module) + tp.members.flatMap(m => + bindingsMap.constructors + .find(_.name == m) + .map(ResolvedConstructor(module, _)) + ) + } + + /** @inheritdoc */ + override def toAbstract: ResolvedType = { + this.copy(module = module.toAbstract) + } + + /** @inheritdoc */ + override def toConcrete( + moduleMap: ModuleMap + ): Option[ResolvedType] = { + module.toConcrete(moduleMap).map(module => this.copy(module = module)) + } + + def qualifiedName: QualifiedName = module.getName.createChild(tp.name) + } + + /** A result of successful name resolution. + */ + sealed trait ResolvedName extends ResolvedTypeName { + + /** Convert the resolved name to abstract form. + * + * @return `this`, converted to abstract form + */ + override def toAbstract: ResolvedName + + /** Convert the resolved name to concrete form. + * + * @param moduleMap the mapping from qualified names to modules + * @return `this`, converted to concrete form + */ + override def toConcrete(moduleMap: ModuleMap): Option[ResolvedName] } /** A representation of a name being resolved to a constructor. @@ -771,6 +847,8 @@ object BindingsMap { ): Option[ResolvedConstructor] = { module.toConcrete(moduleMap).map(module => this.copy(module = module)) } + + def qualifiedName: QualifiedName = module.getName.createChild(cons.name) } /** A representation of a name being resolved to a module. diff --git a/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/AliasAnalysis.scala b/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/AliasAnalysis.scala index 23b4dc96a7a6..09075a9c3a5d 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/AliasAnalysis.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/AliasAnalysis.scala @@ -251,7 +251,8 @@ case object AliasAnalysis extends IRPass { "Annotations should already be associated by the point of alias " + "analysis." ) - case err: IR.Error => err + case err: IR.Error => err + case ut: IR.Module.Scope.Definition.UnionType => ut } } diff --git a/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/BindingAnalysis.scala b/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/BindingAnalysis.scala index ecc95acf960f..f8f4a280b857 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/BindingAnalysis.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/BindingAnalysis.scala @@ -46,6 +46,11 @@ case object BindingAnalysis extends IRPass { ir: IR.Module, moduleContext: ModuleContext ): IR.Module = { + val definedSumTypes = ir.bindings.collect { + case sumType: IR.Module.Scope.Definition.UnionType => + BindingsMap.Type(sumType.name.name, sumType.members.map(_.name)) + } + val definedConstructors = ir.bindings.collect { case cons: IR.Module.Scope.Definition.Atom => BindingsMap.Cons( @@ -85,6 +90,7 @@ case object BindingAnalysis extends IRPass { ) :: moduleMethods ir.updateMetadata( this -->> BindingsMap( + definedSumTypes, definedConstructors, importedPolyglot, methodsWithAutogen, diff --git a/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/CachePreferenceAnalysis.scala b/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/CachePreferenceAnalysis.scala index 2b035a186fa4..2e4179edae2d 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/CachePreferenceAnalysis.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/CachePreferenceAnalysis.scala @@ -93,6 +93,7 @@ case object CachePreferenceAnalysis extends IRPass { arguments.map(analyseDefinitionArgument(_, weights)) ) .updateMetadata(this -->> weights) + case _: IR.Module.Scope.Definition.UnionType => binding case method: Method.Conversion => method .copy(body = analyseExpression(method.body, weights)) diff --git a/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/DataflowAnalysis.scala b/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/DataflowAnalysis.scala index cd520e4178a2..729b43935fb4 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/DataflowAnalysis.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/DataflowAnalysis.scala @@ -154,6 +154,7 @@ case object DataflowAnalysis extends IRPass { method .copy(body = analyseExpression(body, info)) .updateMetadata(this -->> info) + case _: IR.Module.Scope.Definition.UnionType => binding case _: IR.Module.Scope.Definition.Method.Binding => throw new CompilerError( "Sugared method definitions should not occur during dataflow " + diff --git a/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/TailCall.scala b/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/TailCall.scala index df4b6cc6d707..de605e270fa5 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/TailCall.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/TailCall.scala @@ -115,6 +115,7 @@ case object TailCall extends IRPass { arguments = args.map(analyseDefArgument) ) .updateMetadata(this -->> TailPosition.Tail) + case _: IR.Module.Scope.Definition.UnionType => definition case _: IR.Module.Scope.Definition.Type => throw new CompilerError( "Complex type definitions should not be present during " + diff --git a/engine/runtime/src/main/scala/org/enso/compiler/pass/desugar/ComplexType.scala b/engine/runtime/src/main/scala/org/enso/compiler/pass/desugar/ComplexType.scala index 185758f5ca51..bd0d6a91f641 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/pass/desugar/ComplexType.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/pass/desugar/ComplexType.scala @@ -181,7 +181,11 @@ case object ComplexType extends IRPass { } val allEntities = entityResults ::: lastSignature.toList - atomDefs ::: allEntities + val includedNames = atomDefs.map(_.name) + val sumType = IR.Module.Scope.Definition + .UnionType(typ.name, includedNames, typ.location) + + sumType :: atomDefs ::: allEntities } /** Generates a method definition from a definition in complex type def body. diff --git a/engine/runtime/src/main/scala/org/enso/compiler/pass/desugar/FunctionBinding.scala b/engine/runtime/src/main/scala/org/enso/compiler/pass/desugar/FunctionBinding.scala index 7ce5636c24a3..a63b8ec1f527 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/pass/desugar/FunctionBinding.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/pass/desugar/FunctionBinding.scala @@ -130,6 +130,7 @@ case object FunctionBinding extends IRPass { definition match { case a @ Definition.Atom(_, arguments, _, _, _) => a.copy(arguments = arguments.map(_.mapExpressions(desugarExpression))) + case _: Definition.UnionType => definition case _: Method.Explicit => throw new CompilerError( "Explicit method definitions should not exist during function " + diff --git a/engine/runtime/src/main/scala/org/enso/compiler/pass/resolve/DocumentationComments.scala b/engine/runtime/src/main/scala/org/enso/compiler/pass/resolve/DocumentationComments.scala index 7dca77dfeb67..e9943d05fb17 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/pass/resolve/DocumentationComments.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/pass/resolve/DocumentationComments.scala @@ -148,6 +148,10 @@ case object DocumentationComments extends IRPass { "Conversion methods should not yet be present in the compiler " + "pipeline." ) + case _: IR.Module.Scope.Definition.UnionType => + throw new CompilerError( + "Union types should not yet be present in the compiler pipeline." + ) case method: IR.Module.Scope.Definition.Method.Binding => method.copy(body = resolveExpression(method.body)) case method: IR.Module.Scope.Definition.Method.Explicit => diff --git a/engine/runtime/src/main/scala/org/enso/compiler/pass/resolve/SuspendedArguments.scala b/engine/runtime/src/main/scala/org/enso/compiler/pass/resolve/SuspendedArguments.scala index af341f4d2fcb..09a1a0b0639d 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/pass/resolve/SuspendedArguments.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/pass/resolve/SuspendedArguments.scala @@ -174,9 +174,10 @@ case object SuspendedArguments extends IRPass { "Method bodies must be lambdas at this point." ) } - case _: Method.Binding => throw new CompilerError("") - case atom: Definition.Atom => atom - case err: IR.Error => err + case _: Method.Binding => throw new CompilerError("") + case atom: Definition.Atom => atom + case _: Definition.UnionType => binding + case err: IR.Error => err case _: Definition.Type => throw new CompilerError( "Complex type definitions should not be present." diff --git a/engine/runtime/src/main/scala/org/enso/compiler/pass/resolve/TypeSignatures.scala b/engine/runtime/src/main/scala/org/enso/compiler/pass/resolve/TypeSignatures.scala index 86e717347908..e757e0567678 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/pass/resolve/TypeSignatures.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/pass/resolve/TypeSignatures.scala @@ -137,7 +137,8 @@ case object TypeSignatures extends IRPass { res case atom: IR.Module.Scope.Definition.Atom => Some(atom.mapExpressions(resolveExpression)) - case err: IR.Error => Some(err) + case ut: IR.Module.Scope.Definition.UnionType => Some(ut) + case err: IR.Error => Some(err) case _: IR.Module.Scope.Definition.Type => throw new CompilerError( "Complex type definitions should not be present during type " + diff --git a/engine/runtime/src/main/scala/org/enso/compiler/phase/ExportsResolution.scala b/engine/runtime/src/main/scala/org/enso/compiler/phase/ExportsResolution.scala index 104dd9aa3c12..e655cdc59cae 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/phase/ExportsResolution.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/phase/ExportsResolution.scala @@ -171,7 +171,7 @@ class ExportsResolution { List(ResolvedMethod(ModuleReference.Concrete(module), method)) (name, syms) } - val ownConstructors = bindings.types.map { tp => + val ownConstructors = bindings.constructors.map { tp => val name = tp.name.toLowerCase val types = List(ResolvedConstructor(ModuleReference.Concrete(module), tp)) diff --git a/engine/runtime/src/main/scala/org/enso/compiler/phase/StubIrBuilder.scala b/engine/runtime/src/main/scala/org/enso/compiler/phase/StubIrBuilder.scala index ce589408fd9c..4e8cfcbcef11 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/phase/StubIrBuilder.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/phase/StubIrBuilder.scala @@ -51,6 +51,7 @@ object StubIrBuilder { (m.name, List(ResolvedMethod(ModuleReference.Concrete(module), m))) ) val meta = BindingsMap( + List(), definedConstructors, polyglot, moduleMethods, diff --git a/engine/runtime/src/test/scala/org/enso/compiler/test/context/SuggestionBuilderTest.scala b/engine/runtime/src/test/scala/org/enso/compiler/test/context/SuggestionBuilderTest.scala index ea4c73c7cff2..aa3dd4ad2268 100644 --- a/engine/runtime/src/test/scala/org/enso/compiler/test/context/SuggestionBuilderTest.scala +++ b/engine/runtime/src/test/scala/org/enso/compiler/test/context/SuggestionBuilderTest.scala @@ -1,23 +1,33 @@ package org.enso.compiler.test.context -import org.enso.compiler.Passes -import org.enso.compiler.context.{ - FreshNameSupply, - ModuleContext, - SuggestionBuilder -} +import org.enso.compiler.context.SuggestionBuilder import org.enso.compiler.core.IR -import org.enso.compiler.pass.PassManager -import org.enso.compiler.test.CompilerTest +import org.enso.interpreter.runtime +import org.enso.interpreter.runtime.Context +import org.enso.interpreter.test.InterpreterContext import org.enso.pkg.QualifiedName -import org.enso.polyglot.Suggestion +import org.enso.polyglot.{LanguageInfo, MethodNames, Suggestion} import org.enso.polyglot.data.Tree +import org.scalatest.matchers.should.Matchers +import org.scalatest.wordspec.AnyWordSpecLike import java.util.UUID -class SuggestionBuilderTest extends CompilerTest { - - implicit val passManager: PassManager = new Passes(defaultConfig).passManager +class SuggestionBuilderTest extends AnyWordSpecLike with Matchers { + private val ctx = new InterpreterContext() + private val langCtx = ctx.ctx + .getBindings(LanguageInfo.ID) + .invokeMember(MethodNames.TopScope.LEAK_CONTEXT) + .asHostObject[Context]() + + implicit private class PreprocessModule(code: String) { + def preprocessModule: IR.Module = { + val module = new runtime.Module(Module, null, code) + langCtx.getCompiler.run(module) + module.getIr + } + } +// implicit val passManager: PassManager = new Passes(defaultConfig).passManager private val Module = QualifiedName(List("Unnamed"), "Test") private val ModuleNode = Tree.Node( @@ -39,7 +49,6 @@ class SuggestionBuilderTest extends CompilerTest { "SuggestionBuilder" should { "build method without explicit arguments" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """foo = 42""" val module = code.preprocessModule @@ -66,7 +75,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build method with documentation" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """## Module doc @@ -97,7 +105,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build method with type and documentation" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """## Module doc @@ -129,7 +136,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build method with a qualified type" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """ @@ -159,7 +165,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build method with an argument" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """ @@ -190,7 +195,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build method with a type containing higher kinds" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """ @@ -228,7 +232,6 @@ class SuggestionBuilderTest extends CompilerTest { "build method with a type containing qualified higher kinds" in { pending // issue #1711 - implicit val moduleContext: ModuleContext = freshModuleContext val code = """ @@ -258,7 +261,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build method with complex body" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """foo a b = @@ -317,7 +319,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build method with default arguments" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """foo (a = 0) = a + 1""" val module = code.preprocessModule @@ -346,7 +347,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build method with explicit self type" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """type MyType @@ -393,7 +393,6 @@ class SuggestionBuilderTest extends CompilerTest { } "not build method with undefined self type" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """MyAtom.bar a b = a + b""" @@ -403,7 +402,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build method with associated type signature" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """type MyAtom @@ -450,7 +448,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build method with function type signature" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """type MyAtom @@ -495,7 +492,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build method with union type signature" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """type MyAtom @@ -546,7 +542,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build method with lazy arguments" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """foo ~a = a + 1""" @@ -576,7 +571,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build method with resolved type signature" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """type A @@ -620,7 +614,6 @@ class SuggestionBuilderTest extends CompilerTest { "build conversion method for simple type" in { pending - implicit val moduleContext: ModuleContext = freshModuleContext val code = """type MyAtom a @@ -682,7 +675,6 @@ class SuggestionBuilderTest extends CompilerTest { "build conersion method for complex type" in { pending - implicit val moduleContext: ModuleContext = freshModuleContext val code = """type MyMaybe | type Some a @@ -789,7 +781,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build function simple" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """main = @@ -837,7 +828,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build function with complex body" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """main = @@ -901,7 +891,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build function with associated type signature" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """main = @@ -949,7 +938,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build function with resolved type signature" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """type A @@ -1011,7 +999,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build local simple" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """main = @@ -1055,7 +1042,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build local with complex body" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """main = @@ -1115,7 +1101,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build local with associated type signature" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """main = @@ -1160,7 +1145,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build local with resolved type signature" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """type A @@ -1218,7 +1202,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build atom simple" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """type MyType a b""" val module = code.preprocessModule @@ -1277,7 +1260,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build atom with documentation" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """## Module doc @@ -1340,7 +1322,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build type simple" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """type Maybe @@ -1396,7 +1377,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build type with documentation" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """## Module doc @@ -1457,7 +1437,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build type with methods, type signatures and docs" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """type List | ## And more @@ -1506,7 +1485,7 @@ class SuggestionBuilderTest extends CompilerTest { .Argument("this", "Unnamed.Test.Cons", false, false, None) ), selfType = "Unnamed.Test.Cons", - returnType = "List", + returnType = "Unnamed.Test.List", documentation = Some(" a method") ), Vector() @@ -1521,7 +1500,7 @@ class SuggestionBuilderTest extends CompilerTest { .Argument("this", "Unnamed.Test.Nil", false, false, None) ), selfType = "Unnamed.Test.Nil", - returnType = "List", + returnType = "Unnamed.Test.List", documentation = Some(" a method") ), Vector() @@ -1531,7 +1510,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build type with methods, without type signatures" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """type Maybe | type Nothing @@ -1624,7 +1602,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build module with simple atom" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """type MyType a b | @@ -1699,7 +1676,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build module with an atom named as module" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """type Test a | @@ -1757,7 +1733,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build module with overloaded functions" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """type A | type A @@ -1795,7 +1770,14 @@ class SuggestionBuilderTest extends CompilerTest { arguments = Vector( Suggestion .Argument("this", "Unnamed.Test.A", false, false, None), - Suggestion.Argument("x", "Unnamed.Test.A", false, false, None) + Suggestion.Argument( + "x", + "Unnamed.Test.A", + false, + false, + None, + Some(List("Unnamed.Test.A")) + ) ), selfType = "Unnamed.Test.A", returnType = "Unnamed.Test.A", @@ -1810,7 +1792,14 @@ class SuggestionBuilderTest extends CompilerTest { name = "quux", arguments = Vector( Suggestion.Argument("this", "Unnamed.Test", false, false, None), - Suggestion.Argument("x", "Unnamed.Test.A", false, false, None) + Suggestion.Argument( + "x", + "Unnamed.Test.A", + false, + false, + None, + Some(List("Unnamed.Test.A")) + ) ), selfType = "Unnamed.Test", returnType = "Unnamed.Test.A", @@ -1837,7 +1826,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build method with external id" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """main = IO.println "Hello!" | @@ -1871,7 +1859,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build function with external id" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """main = | id x = x @@ -1926,7 +1913,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build local with external id" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """main = | foo = 42 @@ -1977,7 +1963,6 @@ class SuggestionBuilderTest extends CompilerTest { } "build module with documentation" in { - implicit val moduleContext: ModuleContext = freshModuleContext val code = """## Module doc @@ -2012,14 +1997,28 @@ class SuggestionBuilderTest extends CompilerTest { ) ) } + + "provide type variants when applicable" in { + val code = + """type My_Tp + | type Variant_A + | type Variant_B + | + |foo : My_Tp -> My_Tp + |foo arg = arg.do_sth""".stripMargin + val module = code.preprocessModule + val suggestions = build(code, module) + val fooSuggestion = suggestions.collectFirst { + case s: Suggestion.Method if s.name == "foo" => s + } + val fooArg = fooSuggestion.get.arguments(1) + fooArg.reprType shouldEqual "Unnamed.Test.My_Tp" + fooArg.tagValues shouldEqual Some( + List("Unnamed.Test.Variant_A", "Unnamed.Test.Variant_B") + ) + } } private def build(source: String, ir: IR.Module): Tree.Root[Suggestion] = SuggestionBuilder(source).build(Module, ir) - - private def freshModuleContext: ModuleContext = - buildModuleContext( - moduleName = Module, - freshNameSupply = Some(new FreshNameSupply) - ) } diff --git a/engine/runtime/src/test/scala/org/enso/compiler/test/pass/analyse/BindingAnalysisTest.scala b/engine/runtime/src/test/scala/org/enso/compiler/test/pass/analyse/BindingAnalysisTest.scala index cb85be67e056..a320e81032a5 100644 --- a/engine/runtime/src/test/scala/org/enso/compiler/test/pass/analyse/BindingAnalysisTest.scala +++ b/engine/runtime/src/test/scala/org/enso/compiler/test/pass/analyse/BindingAnalysisTest.scala @@ -74,7 +74,7 @@ class BindingAnalysisTest extends CompilerTest { val metadata = ir.unsafeGetMetadata(BindingAnalysis, "Should exist.") - metadata.types shouldEqual List( + metadata.constructors shouldEqual List( Cons("Foo", 3, false), Cons("Bar", 0, true), Cons("Baz", 2, false) diff --git a/engine/runtime/src/test/scala/org/enso/compiler/test/pass/desugar/ComplexTypeTest.scala b/engine/runtime/src/test/scala/org/enso/compiler/test/pass/desugar/ComplexTypeTest.scala index c2929e746fd2..a1ade19e6b0b 100644 --- a/engine/runtime/src/test/scala/org/enso/compiler/test/pass/desugar/ComplexTypeTest.scala +++ b/engine/runtime/src/test/scala/org/enso/compiler/test/pass/desugar/ComplexTypeTest.scala @@ -81,8 +81,12 @@ class ComplexTypeTest extends CompilerTest { |""".stripMargin.preprocessModule.desugar exactly(2, ir.bindings) shouldBe a[Definition.Atom] - ir.bindings.head.asInstanceOf[Definition.Atom].name.name shouldEqual "Foo" - ir.bindings(1).asInstanceOf[Definition.Atom].name.name shouldEqual "Bar" + ir.bindings(0) + .asInstanceOf[Definition.UnionType] + .name + .name shouldEqual "MyType" + ir.bindings(1).asInstanceOf[Definition.Atom].name.name shouldEqual "Foo" + ir.bindings(2).asInstanceOf[Definition.Atom].name.name shouldEqual "Bar" } "have annotations on the type desugared to annotations on the defined" in { @@ -94,7 +98,7 @@ class ComplexTypeTest extends CompilerTest { |""".stripMargin.preprocessModule.desugar exactly(1, ir.bindings) shouldBe a[Definition.Atom] - ir.bindings.head + ir.bindings(1) .asInstanceOf[Definition.Atom] .unsafeGetMetadata(ModuleAnnotations, "") .annotations @@ -103,42 +107,42 @@ class ComplexTypeTest extends CompilerTest { } "have their methods desugared to methods on included atoms" in { - ir.bindings(3) shouldBe an[Definition.Method.Binding] - val justIsJust = ir.bindings(3).asInstanceOf[Definition.Method.Binding] + ir.bindings(4) shouldBe an[Definition.Method.Binding] + val justIsJust = ir.bindings(4).asInstanceOf[Definition.Method.Binding] justIsJust.methodName.name shouldEqual "is_just" justIsJust.typeName.name shouldEqual "Nothing" - ir.bindings(7) shouldBe an[Definition.Method.Binding] - val justF = ir.bindings(7).asInstanceOf[Definition.Method.Binding] + ir.bindings(8) shouldBe an[Definition.Method.Binding] + val justF = ir.bindings(8).asInstanceOf[Definition.Method.Binding] justF.methodName.name shouldEqual "f" justF.typeName.name shouldEqual "Nothing" } "have their methods desugared to methods on the defined atoms" in { - ir.bindings(5) shouldBe an[Definition.Method.Binding] - val justIsJust = ir.bindings(5).asInstanceOf[Definition.Method.Binding] + ir.bindings(6) shouldBe an[Definition.Method.Binding] + val justIsJust = ir.bindings(6).asInstanceOf[Definition.Method.Binding] justIsJust.methodName.name shouldEqual "is_just" justIsJust.typeName.name shouldEqual "Just" - ir.bindings(9) shouldBe an[Definition.Method.Binding] - val justF = ir.bindings(9).asInstanceOf[Definition.Method.Binding] + ir.bindings(10) shouldBe an[Definition.Method.Binding] + val justF = ir.bindings(10).asInstanceOf[Definition.Method.Binding] justF.methodName.name shouldEqual "f" justF.typeName.name shouldEqual "Just" } "have type signatures copied to above each method" in { - ir.bindings(2) shouldBe an[IR.Type.Ascription] - ir.bindings(6) shouldBe an[IR.Type.Ascription] - ir.bindings(4) shouldBe an[IR.Type.Ascription] - ir.bindings(8) shouldBe an[IR.Type.Ascription] + ir.bindings(3) shouldBe an[IR.Type.Ascription] + ir.bindings(7) shouldBe an[IR.Type.Ascription] + ir.bindings(5) shouldBe an[IR.Type.Ascription] + ir.bindings(9) shouldBe an[IR.Type.Ascription] val nothingIsJustSigName = ir - .bindings(2) + .bindings(3) .asInstanceOf[IR.Type.Ascription] .typed .asInstanceOf[IR.Name.MethodReference] val nothingIsJustMethodName = ir - .bindings(3) + .bindings(4) .asInstanceOf[Definition.Method.Binding] .methodReference @@ -148,12 +152,12 @@ class ComplexTypeTest extends CompilerTest { ) val nothingFSigName = ir - .bindings(6) + .bindings(7) .asInstanceOf[IR.Type.Ascription] .typed .asInstanceOf[IR.Name.MethodReference] val nothingFMethodName = ir - .bindings(7) + .bindings(8) .asInstanceOf[Definition.Method.Binding] .methodReference @@ -163,12 +167,12 @@ class ComplexTypeTest extends CompilerTest { ) val justIsJustSigName = ir - .bindings(4) + .bindings(5) .asInstanceOf[IR.Type.Ascription] .typed .asInstanceOf[IR.Name.MethodReference] val justIsJustMethodName = ir - .bindings(5) + .bindings(6) .asInstanceOf[Definition.Method.Binding] .methodReference @@ -178,12 +182,12 @@ class ComplexTypeTest extends CompilerTest { ) val justFSigName = ir - .bindings(8) + .bindings(9) .asInstanceOf[IR.Type.Ascription] .typed .asInstanceOf[IR.Name.MethodReference] val justFMethodName = ir - .bindings(9) + .bindings(10) .asInstanceOf[Definition.Method.Binding] .methodReference @@ -194,15 +198,15 @@ class ComplexTypeTest extends CompilerTest { } "leave un-associated signatures intact" in { - ir.bindings(1) shouldBe an[IR.Type.Ascription] - ir.bindings(1) + ir.bindings(2) shouldBe an[IR.Type.Ascription] + ir.bindings(2) .asInstanceOf[IR.Type.Ascription] .typed .asInstanceOf[IR.Name.Literal] .name shouldEqual "invalid_sig" - ir.bindings(10) shouldBe an[IR.Type.Ascription] - ir.bindings(10) + ir.bindings(11) shouldBe an[IR.Type.Ascription] + ir.bindings(11) .asInstanceOf[IR.Type.Ascription] .typed .asInstanceOf[IR.Name.Literal] @@ -225,8 +229,8 @@ class ComplexTypeTest extends CompilerTest { |""".stripMargin.preprocessModule.desugar "have their types translated untouched" in { - ir.bindings.head shouldBe a[Definition.Atom] - val atom = ir.bindings.head.asInstanceOf[Definition.Atom] + ir.bindings(1) shouldBe a[Definition.Atom] + val atom = ir.bindings(1).asInstanceOf[Definition.Atom] atom.name.name shouldEqual "Baz" } @@ -237,10 +241,10 @@ class ComplexTypeTest extends CompilerTest { } "have their valid methods desugared" in { - ir.bindings(1) shouldBe a[Definition.Method.Binding] ir.bindings(2) shouldBe a[Definition.Method.Binding] - val methodOnBar = ir.bindings(1).asInstanceOf[Definition.Method.Binding] - val methodOnBaz = ir.bindings(2).asInstanceOf[Definition.Method.Binding] + ir.bindings(3) shouldBe a[Definition.Method.Binding] + val methodOnBar = ir.bindings(2).asInstanceOf[Definition.Method.Binding] + val methodOnBaz = ir.bindings(3).asInstanceOf[Definition.Method.Binding] methodOnBar.typeName.name shouldEqual "Bar" methodOnBar.methodName.name shouldEqual "g" methodOnBaz.typeName.name shouldEqual "Baz" diff --git a/engine/runtime/src/test/scala/org/enso/compiler/test/pass/resolve/TypeSignaturesTest.scala b/engine/runtime/src/test/scala/org/enso/compiler/test/pass/resolve/TypeSignaturesTest.scala index 728e58cca9a7..36d578d2c60e 100644 --- a/engine/runtime/src/test/scala/org/enso/compiler/test/pass/resolve/TypeSignaturesTest.scala +++ b/engine/runtime/src/test/scala/org/enso/compiler/test/pass/resolve/TypeSignaturesTest.scala @@ -161,12 +161,12 @@ class TypeSignaturesTest extends CompilerTest { | error_signature : Int |""".stripMargin.preprocessModule.resolve - ir.bindings.length shouldEqual 3 - ir.bindings.head shouldBe an[IR.Module.Scope.Definition.Atom] - ir.bindings(1) shouldBe an[IR.Module.Scope.Definition.Method] - ir.bindings(1).getMetadata(TypeSignatures) shouldBe defined - ir.bindings(1).getMetadata(DocumentationComments) shouldBe defined - ir.bindings(2) shouldBe an[IR.Error.Unexpected.TypeSignature] + ir.bindings.length shouldEqual 4 + ir.bindings(1) shouldBe an[IR.Module.Scope.Definition.Atom] + ir.bindings(2) shouldBe an[IR.Module.Scope.Definition.Method] + ir.bindings(2).getMetadata(TypeSignatures) shouldBe defined + ir.bindings(2).getMetadata(DocumentationComments) shouldBe defined + ir.bindings(3) shouldBe an[IR.Error.Unexpected.TypeSignature] } "recurse into bodies" in {