mirror of
https://github.com/enso-org/enso.git
synced 2025-01-09 01:56:52 +03:00
New Import Syntax (#1070)
This commit is contained in:
parent
1f8a4b802f
commit
b2fbf1a848
@ -219,8 +219,7 @@ object AstToIr {
|
||||
)
|
||||
case _ => Error.Syntax(typed, Error.Syntax.InvalidStandaloneSignature)
|
||||
}
|
||||
case _ =>
|
||||
throw new UnhandledEntity(inputAst, "translateModuleSymbol")
|
||||
case _ => Error.Syntax(inputAst, Error.Syntax.UnexpectedExpression)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -510,15 +510,19 @@ object IR {
|
||||
).flatten
|
||||
|
||||
override def showCode(indent: Int): String = {
|
||||
val renameCode = rename.map(n => s" as $n").getOrElse("")
|
||||
val allCode = if (isAll) " all" else ""
|
||||
val onlyPart = onlyNames
|
||||
.map(names => s" only ${names.mkString(" ")}")
|
||||
.getOrElse("")
|
||||
val hidingPart = hiddenNames
|
||||
.map(names => s" hiding ${names.mkString(" ")}")
|
||||
.getOrElse("")
|
||||
s"import ${name.name}$renameCode$allCode$onlyPart$hidingPart"
|
||||
val renameCode = rename.map(n => s" as ${n.name}").getOrElse("")
|
||||
if (isAll) {
|
||||
val onlyPart = onlyNames
|
||||
.map(names => " " + names.map(_.name).mkString(", "))
|
||||
.getOrElse("")
|
||||
val hidingPart = hiddenNames
|
||||
.map(names => s" hiding ${names.map(_.name).mkString(", ")}")
|
||||
.getOrElse("")
|
||||
val all = if (onlyNames.isDefined) "" else " all"
|
||||
s"from ${name.name}$renameCode import$onlyPart$all$hidingPart"
|
||||
} else {
|
||||
s"import ${name.name}$renameCode"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,4 +1,4 @@
|
||||
import TestNonImportedOverloads.Util all
|
||||
from TestNonImportedOverloads.Util import all
|
||||
|
||||
X.method = 10
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
import TestSimpleImports.Atom all
|
||||
from TestSimpleImports.Atom import all
|
||||
|
||||
Main.main = (X 1).method
|
||||
|
@ -1,3 +1,3 @@
|
||||
import Test_Hiding_Error.Atom all hiding X
|
||||
from Test_Hiding_Error.Atom import all hiding X
|
||||
|
||||
Main.main = (X 1).method
|
||||
|
@ -1,3 +1,3 @@
|
||||
import Test_Hiding_Success.Atom all hiding Y
|
||||
from Test_Hiding_Success.Atom import all hiding Y
|
||||
|
||||
Main.main = (X 1).method
|
||||
|
@ -786,6 +786,23 @@ class AstToIrTest extends CompilerTest with Inside {
|
||||
}
|
||||
}
|
||||
|
||||
"properly support different kinds of imports" in {
|
||||
val imports = List(
|
||||
"import Foo.Bar as Baz",
|
||||
"import Foo.Bar",
|
||||
"from Foo.Bar import Baz",
|
||||
"from Foo.Bar import Baz, Spam",
|
||||
"from Foo.Bar import all",
|
||||
"from Foo.Bar as Eggs import all hiding Spam",
|
||||
"from Foo.Bar import all hiding Spam, Eggs"
|
||||
)
|
||||
imports
|
||||
.mkString("\n")
|
||||
.toIrModule
|
||||
.imports
|
||||
.map(_.showCode()) shouldEqual imports
|
||||
}
|
||||
|
||||
"AST translation of erroneous constructs" should {
|
||||
"result in a syntax error when encountering " +
|
||||
"unbalanced parentheses in application" in {
|
||||
|
@ -267,64 +267,78 @@ object Builtin {
|
||||
case _ => internalError
|
||||
}
|
||||
}
|
||||
val (qualifiedImport, itemsImport) = {
|
||||
val qualNamePat = Pattern.SepList(Pattern.Cons(), Opr("."))
|
||||
val rename = Var("as") :: Pattern.Cons()
|
||||
|
||||
val `import` = {
|
||||
val qualNamePat = Pattern.SepList(Pattern.Cons(), Opr("."))
|
||||
val rename = Var("as") :: Pattern.Cons()
|
||||
val all: Pattern = Var("all")
|
||||
val only: Pattern = Var("only") :: Pattern.Cons().many
|
||||
val hiding: Pattern = Var("hiding") :: Pattern.Cons().many
|
||||
Definition(
|
||||
Var(
|
||||
"import"
|
||||
) -> (qualNamePat :: rename.opt :: (all :: (only | hiding).opt).opt)
|
||||
) { ctx =>
|
||||
ctx.body match {
|
||||
case List(s1) =>
|
||||
val tup1 = s1.body.asInstanceOf[Match.Seq[Shifted[AST]]]
|
||||
val tup2 = tup1.elem._2.asInstanceOf[Match.Seq[Shifted[AST]]]
|
||||
val nameMatch = tup1.elem._1
|
||||
val renameMatch = tup2.elem._1
|
||||
val elemsMatch = tup2.elem._2
|
||||
val name: List1[AST.Ident.Cons] =
|
||||
List1(
|
||||
nameMatch.toStream
|
||||
.map(_.wrapped)
|
||||
.flatMap(AST.Ident.Cons.any.unapply)
|
||||
).get
|
||||
val rename: Option[AST.Ident.Cons] =
|
||||
renameMatch.toStream.map(_.wrapped).collectFirst {
|
||||
case AST.Ident.Cons.any(n) => n
|
||||
def extractRename(
|
||||
matched: Pattern.Match
|
||||
): (List1[AST.Ident.Cons], Option[AST.Ident.Cons]) = {
|
||||
val (nameMatch, renameMatch) =
|
||||
matched.asInstanceOf[Match.Seq[Shifted[AST]]].elem
|
||||
val name: List1[AST.Ident.Cons] =
|
||||
List1(
|
||||
nameMatch.toStream
|
||||
.map(_.wrapped)
|
||||
.flatMap(AST.Ident.Cons.any.unapply)
|
||||
).get
|
||||
val rename: Option[AST.Ident.Cons] = {
|
||||
renameMatch.toStream.map(_.wrapped).collectFirst {
|
||||
case AST.Ident.Cons.any(n) => n
|
||||
}
|
||||
}
|
||||
(name, rename)
|
||||
}
|
||||
|
||||
val itemsImport = {
|
||||
val all: Pattern = Var("all")
|
||||
val items = Pattern.SepList(Pattern.Cons(), Opr(","))
|
||||
val hiding = Var("hiding") :: items
|
||||
|
||||
Definition(
|
||||
Var("from") -> (qualNamePat :: rename.opt),
|
||||
Var("import") -> ((all :: hiding.opt) | items)
|
||||
) { ctx =>
|
||||
ctx.body match {
|
||||
case List(imp, itemsMatch) =>
|
||||
val (name, rename) = extractRename(imp.body)
|
||||
val (hiding, items) = itemsMatch.body match {
|
||||
case Match.Or(_, Left(hidden)) =>
|
||||
val hiddenItems = hidden.toStream
|
||||
.map(_.wrapped)
|
||||
.flatMap(AST.Ident.Cons.any.unapply)
|
||||
(List1(hiddenItems), None)
|
||||
|
||||
case Match.Or(_, Right(imported)) =>
|
||||
val importedItems = imported.toStream
|
||||
.map(_.wrapped)
|
||||
.flatMap(AST.Ident.Cons.any.unapply)
|
||||
(None, List1(importedItems))
|
||||
case _ => internalError
|
||||
}
|
||||
val (isAll, only, hiding) = elemsMatch match {
|
||||
case Match.Or(_, Left(Match.Seq(_, (_, onlyHidingMaybeMatch)))) =>
|
||||
onlyHidingMaybeMatch match {
|
||||
case Match.Or(_, Left(maybeHidingMatch)) =>
|
||||
maybeHidingMatch match {
|
||||
case Match.Or(_, Left(onlyMatch)) =>
|
||||
val onlyConses: List[AST.Ident.Cons] =
|
||||
onlyMatch.toStream
|
||||
.map(_.wrapped)
|
||||
.flatMap(AST.Ident.Cons.any.unapply)
|
||||
(true, List1(onlyConses), None)
|
||||
case Match.Or(_, Right(hidingMatch)) =>
|
||||
val hidingConses: List[AST.Ident.Cons] =
|
||||
hidingMatch.toStream
|
||||
.map(_.wrapped)
|
||||
.flatMap(AST.Ident.Cons.any.unapply)
|
||||
(true, None, List1(hidingConses))
|
||||
case _ => internalError
|
||||
}
|
||||
case _ => (true, None, None)
|
||||
}
|
||||
case _ => (false, None, None)
|
||||
}
|
||||
AST.Import(name, rename, isAll, only, hiding)
|
||||
case _ => internalError
|
||||
AST.Import(name, rename, true, items, hiding)
|
||||
case _ => internalError
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val qualifiedImport = {
|
||||
Definition(
|
||||
Var(
|
||||
"import"
|
||||
) -> (qualNamePat :: rename.opt)
|
||||
) { ctx =>
|
||||
ctx.body match {
|
||||
case List(s1) =>
|
||||
val (name, rename) = extractRename(s1.body)
|
||||
AST.Import(name, rename, false, None, None)
|
||||
case _ => internalError
|
||||
}
|
||||
}
|
||||
}
|
||||
(qualifiedImport, itemsImport)
|
||||
}
|
||||
val privateDef = {
|
||||
Definition(Var("private") -> Pattern.Expr()) { ctx =>
|
||||
ctx.body match {
|
||||
@ -373,7 +387,8 @@ object Builtin {
|
||||
if_then,
|
||||
if_then_else,
|
||||
polyglotJavaImport,
|
||||
`import`,
|
||||
itemsImport,
|
||||
qualifiedImport,
|
||||
defn,
|
||||
arrow,
|
||||
foreign,
|
||||
|
@ -1,3 +1,3 @@
|
||||
import Test.Import_Loop.B all only My_Type
|
||||
from Test.Import_Loop.B import My_Type
|
||||
|
||||
foo = My_Type.bar 10
|
||||
|
@ -1,4 +1,4 @@
|
||||
import Test.Names.Definitions all only My_Type Another_Constant
|
||||
from Test.Names.Definitions import My_Type, Another_Constant
|
||||
import Base.Test
|
||||
|
||||
Definitions.Foo.my_method = case this of
|
||||
|
Loading…
Reference in New Issue
Block a user