diff --git a/shared/src/main/scala/mlscript/JSBackend.scala b/shared/src/main/scala/mlscript/JSBackend.scala index 82fdb2f535..4f42d57d96 100644 --- a/shared/src/main/scala/mlscript/JSBackend.scala +++ b/shared/src/main/scala/mlscript/JSBackend.scala @@ -463,6 +463,7 @@ class JSBackend(allowUnresolvedSymbols: Boolean) { traits += topLevelScope.declareTrait(name, tparams map { _.name }, body, methods) case TypeDef(Cls, TypeName(name), tparams, baseType, _, members, _) => classes += topLevelScope.declareClass(name, tparams map { _.name }, baseType, members) + case TypeDef(Nms, _, _, _, _, _, _) => throw CodeGenError("Namespaces are not supported yet.") } (traits.toList, classes.toList) } diff --git a/shared/src/main/scala/mlscript/MLParser.scala b/shared/src/main/scala/mlscript/MLParser.scala index 6ee0f88074..981438b3e4 100644 --- a/shared/src/main/scala/mlscript/MLParser.scala +++ b/shared/src/main/scala/mlscript/MLParser.scala @@ -204,6 +204,7 @@ class MLParser(origin: Origin, indent: Int = 0, recordLocations: Bool = true) { ms.collect { case R(md) => md }, ms.collect{ case L(md) => md }, Nil) } case (k @ Als, id, ts) => "=" ~ ty map (bod => TypeDef(k, id, ts, bod, Nil, Nil, Nil)) + case (k @ Nms, _, _) => throw new NotImplementedError("Namespaces are not supported yet.") }) def tyParams[p: P]: P[Ls[TypeName]] = ("[" ~ tyName.rep(0, ",") ~ "]").?.map(_.toList.flatten) diff --git a/shared/src/main/scala/mlscript/NewLexer.scala b/shared/src/main/scala/mlscript/NewLexer.scala index 7cd31204aa..d2d54cf64f 100644 --- a/shared/src/main/scala/mlscript/NewLexer.scala +++ b/shared/src/main/scala/mlscript/NewLexer.scala @@ -84,6 +84,16 @@ class NewLexer(origin: Origin, raise: Diagnostic => Unit, dbg: Bool) { val (txt, k) = takeWhile(j)(c => c =/= '\n') go(k, COMMENT(txt)) + case '/' if bytes.lift(i + 1).contains('*') => // multiple-line comment + val j = i + 2 + var prev1 = '/'; var prev2 = '*' + val (txt, k) = + takeWhile(j)(c => { + val res = prev1 =/= '*' || prev2 =/= '/' + prev1 = prev2; prev2 = c + res + }) + go(k, COMMENT(txt.dropRight(2))) case BracketKind(Left(k)) => go(i + 1, OPEN_BRACKET(k)) case BracketKind(Right(k)) => go(i + 1, CLOSE_BRACKET(k)) case '\n' => @@ -164,7 +174,7 @@ class NewLexer(origin: Origin, raise: Diagnostic => Unit, dbg: Bool) { if (k0 =/= k1) raise(ErrorReport(msg"Mistmatched closing ${k1.name}" -> S(l1) :: msg"does not correspond to opening ${k0.name}" -> S(l0) :: Nil, source = Parsing)) - go(rest, false, stack, BRACKETS(k0, acc.reverse)(l0.right ++ l1.left) -> (l0 ++ l1) :: oldAcc) + go(rest, true, stack, BRACKETS(k0, acc.reverse)(l0.right ++ l1.left) -> (l0 ++ l1) :: oldAcc) case Nil => raise(ErrorReport(msg"Unexpected closing ${k1.name}" -> S(l1) :: Nil, source = Parsing)) go(rest, false, stack, acc) @@ -180,6 +190,12 @@ class NewLexer(origin: Origin, raise: Diagnostic => Unit, dbg: Bool) { case _ => false }) => go(CLOSE_BRACKET(Angle) -> loc :: rest, false, stack, acc) + case (IDENT(id, true), loc) :: rest + if (canStartAngles && id.forall(_ == '>') && id.length > 1 && (stack match { + case ((Angle, _), _) :: _ => true + case _ => false + })) => // split `>>` to `>` and `>` so that code like `A>` can be parsed correctly + go((CLOSE_BRACKET(Angle) -> loc.left) :: (IDENT(id.drop(1), true) -> loc) :: rest, false, stack, acc) case ((tk @ IDENT(">", true), loc)) :: rest if canStartAngles => raise(WarningReport(msg"This looks like an angle bracket, but it does not close any angle bracket section" -> S(loc) :: msg"Add spaces around it if you intended to use `<` as an operator" -> N :: Nil, source = Parsing)) @@ -234,6 +250,7 @@ object NewLexer { "trait", "interface", "new", + "namespace" ) def printToken(tl: TokLoc): Str = tl match { diff --git a/shared/src/main/scala/mlscript/NewParser.scala b/shared/src/main/scala/mlscript/NewParser.scala index 78c5e3fe11..44a10ee2aa 100644 --- a/shared/src/main/scala/mlscript/NewParser.scala +++ b/shared/src/main/scala/mlscript/NewParser.scala @@ -137,6 +137,10 @@ abstract class NewParser(origin: Origin, tokens: Ls[Stroken -> Loc], raiseFun: D private def cur(implicit l: Line, n: Name) = { if (dbg) printDbg(s"? ${n.value}\t\tinspects ${summarizeCur} [at l.${l.value}]") + while (!_cur.isEmpty && (_cur.head._1 match { + case COMMENT(_) => true + case _ => false + })) consume _cur } @@ -235,12 +239,13 @@ abstract class NewParser(origin: Origin, tokens: Ls[Stroken -> Loc], raiseFun: D case (SPACE, _) :: _ => consume; block case c => val t = c match { - case (KEYWORD(k @ ("class" | "trait" | "type")), l0) :: c => + case (KEYWORD(k @ ("class" | "trait" | "type" | "namespace")), l0) :: c => consume val kind = k match { case "class" => Cls case "trait" => Trt case "type" => Als + case "namespace" => Nms case _ => die } val (tn, success) = yeetSpaces match { @@ -306,6 +311,17 @@ abstract class NewParser(origin: Origin, tokens: Ls[Stroken -> Loc], raiseFun: D (Var("").withLoc(curLoc.map(_.left)), false) } foundErr || !success pipe { implicit fe => + val tparams = if (kwStr === "let") Ls[TypeName]() else yeetSpaces match { + case (br @ BRACKETS(Angle, toks), loc) :: _ => + consume + val ts = rec(toks, S(br.innerLoc), br.describe).concludeWith(_.argsMaybeIndented()).map { + case (N, Fld(false, false, v @ Var(nme))) => + TypeName(nme).withLocOf(v) + case _ => ??? + } + ts + case _ => Nil + } val ps = funParams val asc = yeetSpaces match { case (KEYWORD(":"), _) :: _ => @@ -318,11 +334,11 @@ abstract class NewParser(origin: Origin, tokens: Ls[Stroken -> Loc], raiseFun: D consume val body = expr(0) val annotatedBody = asc.fold(body)(ty => Asc(body, ty)) - R(NuFunDef(isLetRec, v, Nil, L(ps.foldRight(annotatedBody)((i, acc) => Lam(i, acc))))) + R(NuFunDef(isLetRec, v, tparams, L(ps.foldRight(annotatedBody)((i, acc) => Lam(i, acc))))) case c => asc match { case S(ty) => - R(NuFunDef(isLetRec, v, Nil, R(PolyType(Nil, ps.foldRight(ty)((p, r) => Function(p.toType match { + R(NuFunDef(isLetRec, v, tparams, R(PolyType(Nil, ps.foldRight(ty)((p, r) => Function(p.toType match { case L(diag) => raise(diag); Top // TODO better case R(tp) => tp }, r)))))) // TODO rm PolyType after FCP is merged diff --git a/shared/src/main/scala/mlscript/TypeDefs.scala b/shared/src/main/scala/mlscript/TypeDefs.scala index eb81db2f31..3c2564c436 100644 --- a/shared/src/main/scala/mlscript/TypeDefs.scala +++ b/shared/src/main/scala/mlscript/TypeDefs.scala @@ -227,6 +227,9 @@ class TypeDefs extends NuTypeDefs { self: Typer => val rightParents = td.kind match { case Als => checkCycle(td.bodyTy)(Set.single(L(td.nme))) + case Nms => + err(msg"a namespace cannot inherit from others", prov.loco) + false case k: ObjDefKind => val parentsClasses = MutSet.empty[TypeRef] def checkParents(ty: SimpleType): Bool = ty match { @@ -246,6 +249,9 @@ class TypeDefs extends NuTypeDefs { self: Typer => } else checkParents(tr.expand) case Trt => checkParents(tr.expand) + case Nms => + err(msg"cannot inherit from a namespace", prov.loco) + false case Als => err(msg"cannot inherit from a type alias", prov.loco) false diff --git a/shared/src/main/scala/mlscript/Typer.scala b/shared/src/main/scala/mlscript/Typer.scala index 055015c21c..8712af4827 100644 --- a/shared/src/main/scala/mlscript/Typer.scala +++ b/shared/src/main/scala/mlscript/Typer.scala @@ -308,6 +308,8 @@ class Typer(var dbg: Boolean, var verbose: Bool, var explainErrors: Bool) case Trt => trtNameToNomTag(td)(tyTp(tyLoc, "trait tag"), ctx) case Als => err( msg"Type alias ${name.capitalize} cannot be used as a type tag", tyLoc)(raise) + case Nms => err( + msg"Namespaces ${name.capitalize} cannot be used as a type tag", tyLoc)(raise) } case _ => e() } @@ -751,6 +753,7 @@ class Typer(var dbg: Boolean, var verbose: Bool, var explainErrors: Bool) case Some(td) => td.kind match { case Als => err(msg"can only match on classes and traits", pat.toLoc)(raise) + case Nms => err(msg"can only match on classes and traits", pat.toLoc)(raise) case Cls => clsNameToNomTag(td)(tp(pat.toLoc, "class pattern"), ctx) case Trt => trtNameToNomTag(td)(tp(pat.toLoc, "trait pattern"), ctx) } diff --git a/shared/src/main/scala/mlscript/TyperDatatypes.scala b/shared/src/main/scala/mlscript/TyperDatatypes.scala index 089fb8739e..099e4f76f0 100644 --- a/shared/src/main/scala/mlscript/TyperDatatypes.scala +++ b/shared/src/main/scala/mlscript/TyperDatatypes.scala @@ -234,6 +234,7 @@ abstract class TyperDatatypes extends TyperHelpers { self: Typer => else TopType subst(td.kind match { case Als => td.bodyTy + case Nms => throw new NotImplementedError("Namespaces are not supported yet.") case Cls => clsNameToNomTag(td)(prov, ctx) & td.bodyTy & tparamTags case Trt => trtNameToNomTag(td)(prov, ctx) & td.bodyTy & tparamTags }, td.targs.lazyZip(targs).toMap) //.withProv(prov) diff --git a/shared/src/main/scala/mlscript/codegen/Scope.scala b/shared/src/main/scala/mlscript/codegen/Scope.scala index 61a794178b..92810909cb 100644 --- a/shared/src/main/scala/mlscript/codegen/Scope.scala +++ b/shared/src/main/scala/mlscript/codegen/Scope.scala @@ -4,7 +4,7 @@ import mlscript.utils.shorthands._ import mlscript.{JSStmt, JSExpr, JSLetDecl} import mlscript.Type import scala.reflect.ClassTag -import mlscript.{TypeName, Top, Bot, TypeDef, Als, Trt, Cls} +import mlscript.{TypeName, Top, Bot, TypeDef, Als, Trt, Cls, Nms} import mlscript.MethodDef import mlscript.Term import mlscript.utils.{AnyOps, lastWords} @@ -200,6 +200,8 @@ class Scope(name: Str, enclosing: Opt[Scope]) { declareTrait(name, tparams map { _.name }, body, mthdDefs) case TypeDef(Cls, TypeName(name), tparams, baseType, _, members, _) => declareClass(name, tparams map { _.name }, baseType, members) + case TypeDef(Nms, _, _, _, _, _, _) => + throw CodeGenError("Namespaces are not supported yet.") } def declareClass( diff --git a/shared/src/main/scala/mlscript/helpers.scala b/shared/src/main/scala/mlscript/helpers.scala index 9ba7343ebd..2799a1d331 100644 --- a/shared/src/main/scala/mlscript/helpers.scala +++ b/shared/src/main/scala/mlscript/helpers.scala @@ -429,6 +429,11 @@ trait TermImpl extends StatementImpl { self: Term => case Tup(fields) => Tuple(fields.map(fld => (fld._1, fld._2 match { case Fld(m, s, v) => val ty = v.toType_!; Field(Option.when(m)(ty), ty) }))) + case Bra(rcd, trm) if (!rcd) => trm.toType_! + case TyApp(lhs, targs) => lhs.toType_! match { + case p: TypeName => AppliedType(p, targs) + case _ => throw new NotAType(this) + } // TODO: // case Rcd(fields) => ??? // case Sel(receiver, fieldName) => ??? diff --git a/shared/src/main/scala/mlscript/syntax.scala b/shared/src/main/scala/mlscript/syntax.scala index 3e434ce689..06facf4035 100644 --- a/shared/src/main/scala/mlscript/syntax.scala +++ b/shared/src/main/scala/mlscript/syntax.scala @@ -48,6 +48,7 @@ sealed trait ObjDefKind case object Cls extends TypeDefKind("class") with ObjDefKind case object Trt extends TypeDefKind("trait") with ObjDefKind case object Als extends TypeDefKind("type alias") +case object Nms extends TypeDefKind("namespace") sealed abstract class Term extends Terms with TermImpl sealed abstract class Lit extends SimpleTerm with LitImpl diff --git a/shared/src/test/diff/parser/Comments.mls b/shared/src/test/diff/parser/Comments.mls index 9dc5cdda90..a7c2f6a4f5 100644 --- a/shared/src/test/diff/parser/Comments.mls +++ b/shared/src/test/diff/parser/Comments.mls @@ -2,14 +2,8 @@ // TODO comments 1 // whoops //│ |1| |/* whoops*/| -//│ ╔══[PARSE ERROR] Unexpected comment in expression position -//│ ║ l.3: 1 // whoops -//│ ╙── ^^^^^^^^^ -//│ ╔══[PARSE ERROR] Unexpected end of input; an expression was expected here -//│ ║ l.3: 1 // whoops -//│ ╙── ^ -//│ ╔══[WARNING] Paren-less applications should use the 'of' keyword -//│ ║ l.3: 1 // whoops -//│ ╙── ^^^^^^^^^^^ -//│ Parsed: {1 (undefined,)} +//│ Parsed: {1} +2 /* whoops */ +//│ |2| |/* whoops */| +//│ Parsed: {2} diff --git a/shared/src/test/diff/parser/TypeParams.mls b/shared/src/test/diff/parser/TypeParams.mls index d93402b47b..ab6918b6ad 100644 --- a/shared/src/test/diff/parser/TypeParams.mls +++ b/shared/src/test/diff/parser/TypeParams.mls @@ -115,3 +115,14 @@ foo[S, T](1, 2, 3) & Bar[U]("ok") //│ ╙── ^ //│ Parsed: {& ((foo)[S] (1, 2, 3,),) ((Bar)[U] ("ok",),)} +class Foo {} +//│ |#class| |Foo|‹|T|›| |{||}| +//│ Parsed: {class Foo[T]() {}} + +fun foo(x: T): string = "rua" +//│ |#fun| |foo|‹|T|›|(|x|#:| |T|)|#:| |string| |#=| |"rua"| +//│ Parsed: {fun foo = x: T, => "rua" : TypeName(string)} + +foo(42) +//│ |foo|‹|int|›|(|42|)| +//│ Parsed: {foo‹int› (42,)} diff --git a/ts2mls/js/src/main/scala/ts2mls/JSWriter.scala b/ts2mls/js/src/main/scala/ts2mls/JSWriter.scala index bc4065a58f..b29ae08f7c 100644 --- a/ts2mls/js/src/main/scala/ts2mls/JSWriter.scala +++ b/ts2mls/js/src/main/scala/ts2mls/JSWriter.scala @@ -11,6 +11,8 @@ class JSWriter(filename: String) { private var fileSize = 0 // how many bytes we've written in the file private var needTruncate = false + writeln(":NewParser\n:ParseOnly") + def writeln(str: String) = { val strln = str + "\n" val buffer = createBuffer(strln.length) diff --git a/ts2mls/js/src/main/scala/ts2mls/TSNamespace.scala b/ts2mls/js/src/main/scala/ts2mls/TSNamespace.scala index c45834c75e..4546290287 100644 --- a/ts2mls/js/src/main/scala/ts2mls/TSNamespace.scala +++ b/ts2mls/js/src/main/scala/ts2mls/TSNamespace.scala @@ -2,6 +2,7 @@ package ts2mls import scala.collection.mutable.{HashMap, ListBuffer} import types._ +import mlscript.utils._ class TSNamespace(name: String, parent: Option[TSNamespace]) { private val subSpace = HashMap[String, TSNamespace]() @@ -34,40 +35,29 @@ class TSNamespace(name: String, parent: Option[TSNamespace]) { def containsMember(name: String, searchParent: Boolean = true): Boolean = if (parent.isEmpty) members.contains(name) else (members.contains(name) || (searchParent && parent.get.containsMember(name))) - def generate(writer: JSWriter): Unit = + def generate(writer: JSWriter, indent: String): Unit = order.toList.foreach((p) => p match { - case Left(name) => subSpace(name).generate(writer) + case Left(subName) => { + writer.writeln(s"${indent}namespace $subName {") + subSpace(subName).generate(writer, indent + " ") + writer.writeln(s"$indent}") + } case Right(name) => { val mem = members(name) - val fullName = getFullPath(name) mem match { case inter: TSIntersectionType => // overloaded functions - writer.writeln(s"def ${fullName}: ${Converter.convert(inter)}") - case f: TSFunctionType => { - val typeParams = f.typeVars.map((t) => t.name) - if (typeParams.isEmpty) - writer.writeln(s"def ${fullName}: ${Converter.convert(f)}") - else // TODO: add constraints - writer.writeln(s"def ${fullName}[${typeParams.reduceLeft((r, s) => s"$r, $s")}]: ${Converter.convert(f)}") - } - case overload @ TSIgnoredOverload(base, _) => { - val typeParams = base.typeVars.map((t) => t.name) - if (typeParams.isEmpty) - writer.writeln(s"def ${fullName}: ${Converter.convert(overload)}") - else // TODO: add constraints - writer.writeln(s"def ${fullName}[${typeParams.reduceLeft((r, s) => s"$r, $s")}]: ${Converter.convert(overload)}") - } + writer.writeln(Converter.generateFunDeclaration(inter, name)(indent)) + case f: TSFunctionType => + writer.writeln(Converter.generateFunDeclaration(f, name)(indent)) + case overload: TSIgnoredOverload => + writer.writeln(Converter.generateFunDeclaration(overload, name)(indent)) + case _: TSClassType => writer.writeln(Converter.convert(mem)(indent)) + case TSInterfaceType(name, _, _, _) if (name =/= "") => + writer.writeln(Converter.convert(mem)(indent)) case _ => writer.writeln(Converter.convert(mem)) } } }) - - // generate full path with namespaces' names - // e.g. f => Namespace1.Namespace2.f - def getFullPath(nm: String): String = parent match { - case Some(p) => p.getFullPath(s"$name'$nm") - case _ => nm - } } object TSNamespace { diff --git a/ts2mls/js/src/main/scala/ts2mls/TSProgram.scala b/ts2mls/js/src/main/scala/ts2mls/TSProgram.scala index 8660ad397b..631e08df61 100644 --- a/ts2mls/js/src/main/scala/ts2mls/TSProgram.scala +++ b/ts2mls/js/src/main/scala/ts2mls/TSProgram.scala @@ -15,7 +15,7 @@ class TSProgram(filenames: Seq[String]) { implicit val checker = TSTypeChecker(program.getTypeChecker()) filenames.foreach(filename => TSSourceFile(program.getSourceFile(filename), globalNamespace)) - def generate(writer: JSWriter): Unit = globalNamespace.generate(writer) + def generate(writer: JSWriter): Unit = globalNamespace.generate(writer, "") } object TSProgram { diff --git a/ts2mls/js/src/main/scala/ts2mls/TSSourceFile.scala b/ts2mls/js/src/main/scala/ts2mls/TSSourceFile.scala index 41516fa7ba..90fca4398f 100644 --- a/ts2mls/js/src/main/scala/ts2mls/TSSourceFile.scala +++ b/ts2mls/js/src/main/scala/ts2mls/TSSourceFile.scala @@ -49,12 +49,13 @@ object TSSourceFile { ) private def getFunctionType(node: TSNodeObject): TSFunctionType = { - val pList = node.parameters.foldLeft(List[TSType]())((lst, p) => lst :+ ( + val pList = node.parameters.foldLeft(List[TSParameterType]())((lst, p) => ( // in typescript, you can use `this` to explicitly specifies the callee // but it never appears in the final javascript file - if (p.symbol.escapedName === "this") TSPrimitiveType("void") - else if (p.isOptionalParameter) TSUnionType(getObjectType(p.symbolType), TSPrimitiveType("undefined")) - else getObjectType(p.symbolType)) + if (p.symbol.escapedName === "this") lst + else if (p.isOptionalParameter) + lst :+ TSParameterType(p.symbol.escapedName, TSUnionType(getObjectType(p.symbolType), TSPrimitiveType("undefined"))) + else lst :+ TSParameterType(p.symbol.escapedName, getObjectType(p.symbolType))) ) TSFunctionType(pList, getObjectType(node.returnType), getTypeParametes(node)) } @@ -78,7 +79,6 @@ object TSSourceFile { list.foldLeft(Map[String, TSMemberType]())((mp, p) => { val name = p.symbol.escapedName - // TODO: support `__constructor` if (name =/= "__constructor" && p.isStatic == requireStatic) { val mem = if (!p.isStatic) getMemberType(p) @@ -111,6 +111,15 @@ object TSSourceFile { else mp }) + private def getConstructorList(members: TSNodeArray): List[TSParameterType] = + members.foldLeft(List[TSParameterType]())((lst, mem) => { + val name = mem.symbol.escapedName + + if (name =/= "__constructor") lst + else mem.parameters.foldLeft(List[TSParameterType]())((res, p) => + res :+ TSParameterType(p.symbol.escapedName, getMemberType(p))) + }) + private def getInterfacePropertiesType(list: TSNodeArray): Map[String, TSMemberType] = list.foldLeft(Map[String, TSMemberType]())((mp, p) => mp ++ Map(p.symbol.escapedName -> TSMemberType(getMemberType(p)))) @@ -120,7 +129,8 @@ object TSSourceFile { private def parseMembers(name: String, node: TSNodeObject, isClass: Boolean): TSType = if (isClass) - TSClassType(name, getClassMembersType(node.members, false), getClassMembersType(node.members, true), getTypeParametes(node), getHeritageList(node)) + TSClassType(name, getClassMembersType(node.members, false), getClassMembersType(node.members, true), + getTypeParametes(node), getHeritageList(node), getConstructorList(node.members)) else TSInterfaceType(name, getInterfacePropertiesType(node.members), getTypeParametes(node), getHeritageList(node)) private def parseNamespaceLocals(map: TSSymbolMap)(implicit ns: TSNamespace) = @@ -163,9 +173,9 @@ object TSSourceFile { } } else if (node.isClassDeclaration) - ns.put(name, parseMembers(ns.getFullPath(name), node, true)) + ns.put(name, parseMembers(name, node, true)) else if (node.isInterfaceDeclaration) - ns.put(name, parseMembers(ns.getFullPath(name), node, false)) + ns.put(name, parseMembers(name, node, false)) else if (node.isNamespace) parseNamespace(node) diff --git a/ts2mls/js/src/main/scala/ts2mls/types/Converter.scala b/ts2mls/js/src/main/scala/ts2mls/types/Converter.scala index be2cf33173..1cb716c6a0 100644 --- a/ts2mls/js/src/main/scala/ts2mls/types/Converter.scala +++ b/ts2mls/js/src/main/scala/ts2mls/types/Converter.scala @@ -13,65 +13,84 @@ object Converter { "null" -> "null", "undefined" -> "undefined", "never" -> "nothing", - "object" -> "{}", + "object" -> "object", "true" -> "true", "false" -> "false" ) - def convert(tsType: TSType): String = tsType match { + def generateFunDeclaration(tsType: TSType, name: String)(implicit indent: String = ""): String = tsType match { + case TSFunctionType(params, res, typeVars) => { + val pList = if (params.isEmpty) "" else params.map(p => s"${convert(p)("")}").reduceLeft((r, p) => s"$r, $p") + val tpList = if (typeVars.isEmpty) "" else s"<${typeVars.map(p => convert(p)("")).reduceLeft((r, p) => s"$r, $p")}>" + s"${indent}fun $name$tpList($pList): ${convert(res)("")}" + } + case overload @ TSIgnoredOverload(base, _) => s"${generateFunDeclaration(base, name)} ${overload.warning}" + case inter: TSIntersectionType => s"${indent}fun ${name}: ${Converter.convert(inter)}" + case _ => throw new AssertionError("non-function type is not allowed.") + } + + def convert(tsType: TSType)(implicit indent: String = ""): String = tsType match { case TSPrimitiveType(typeName) => primitiveName(typeName) case TSReferenceType(name) => name case TSFunctionType(params, res, _) => - // since functions can be defined by both `def` and `method`, it only returns the type of functions - if (params.length == 0) s"${primitiveName("void")} -> (${convert(res)})" - else params.foldRight(convert(res))((tst, mlst) => s"(${convert(tst)}) -> (${mlst})") + if (params.length == 0) s"${primitiveName("void")} => ${convert(res)}" + else + params.foldRight(convert(res))((p, f) => s"(${convert(p.tp)}) => $f") case TSUnionType(lhs, rhs) => s"(${convert(lhs)}) | (${convert(rhs)})" case TSIntersectionType(lhs, rhs) => s"(${convert(lhs)}) & (${convert(rhs)})" case TSTypeParameter(name, _) => name // constraints should be translated where the type parameters were created rather than be used case TSTupleType(lst) => s"(${lst.foldLeft("")((p, t) => s"$p${convert(t)}, ")})" - case TSArrayType(element) => s"MutArray[${convert(element)}]" + case TSArrayType(element) => s"MutArray<${convert(element)}>" case TSEnumType => "int" case TSMemberType(base, _) => convert(base) // TODO: support private/protected members - case TSInterfaceType(name, members, typeVars, parents) => convertRecord(s"trait $name", members, typeVars, parents) - case TSClassType(name, members, _, typeVars, parents) => convertRecord(s"class $name", members, typeVars, parents) // TODO: support static members - case TSSubstitutionType(base, applied) => s"${base}[${applied.map((app) => convert(app)).reduceLeft((res, s) => s"$res, $s")}]" + case TSInterfaceType(name, members, typeVars, parents) => + convertRecord(s"trait $name", members, typeVars, parents, Map(), List())(indent) + case TSClassType(name, members, statics, typeVars, parents, cons) => + convertRecord(s"class $name", members, typeVars, parents, statics, cons)(indent) + case TSSubstitutionType(base, applied) => s"${base}<${applied.map((app) => convert(app)).reduceLeft((res, s) => s"$res, $s")}>" case overload @ TSIgnoredOverload(base, _) => s"${convert(base)} ${overload.warning}" + case TSParameterType(name, tp) => s"${name}: ${convert(tp)}" } - private def convertRecord(typeName: String, members: Map[String, TSMemberType], - typeVars: List[TSTypeParameter], parents: List[TSType]) = { + private def convertRecord(typeName: String, members: Map[String, TSMemberType], typeVars: List[TSTypeParameter], + parents: List[TSType], statics: Map[String, TSMemberType], constructorList: List[TSType])(implicit indent: String) = { val allRecs = members.toList.map((m) => m._2.modifier match { - case Public => { - m._2.base match { // methods - case f @ TSFunctionType(_, _, typeVars) if (!typeVars.isEmpty) => - s" method ${m._1}[${typeVars.map((tv) => tv.name).reduceLeft((p, s) => s"$p, $s")}]: ${convert(f)}" // TODO: add constraints - case overload @ TSIgnoredOverload(base, _) => - if (!base.typeVars.isEmpty) - s" method ${m._1}[${base.typeVars.map((tv) => tv.name).reduceLeft((p, s) => s"$p, $s")}]: ${convert(overload)}" // TODO: add constraints - else s"${m._1}: ${convert(overload)}" - case _ => s"${m._1}: ${convert(m._2)}" // other type members + case Public => + if (typeName === "trait ") s"${m._1}: ${convert(m._2)}," + else m._2.base match { + case _: TSFunctionType => s"${generateFunDeclaration(m._2.base, m._1)(indent + " ")}\n" + case _: TSIgnoredOverload => s"${generateFunDeclaration(m._2.base, m._1)(indent + " ")}\n" + case _ => s"${indent} let ${m._1}: ${convert(m._2)}\n" } - } case _ => "" // TODO: deal with private/protected members - }) + }) ::: + statics.toList.map((s) => s._2.modifier match { + case Public => s._2.base match { + case _: TSClassType => convert(s._2)(indent + " ") + "\n" + case _ => "" // TODO: deal with other static type + } + case _ => "" // TODO: deal with private/protected static members + }) val body = { // members without independent type parameters, translate them directly - val lst = allRecs.filter((s) => !s.startsWith(" ") && !s.isEmpty()) + val lst = allRecs.filter((s) => !s.isEmpty()) if (lst.isEmpty) "{}" - else s"{ ${lst.reduceLeft((bd, m) => s"$bd; $m")} }" - } - val methods = { // members with independent type parameters, use methods instead - val lst = allRecs.filter(_.startsWith(" ")) - if (lst.isEmpty) "" - else "\n" + lst.reduceLeft((bd, m) => s"$bd\n$m") + else if (typeName === "trait ") s"(${lst.reduceLeft((bd, m) => s"$bd$m")})" + else s"{\n${lst.reduceLeft((bd, m) => s"$bd$m")}$indent}" } if (typeName === "trait ") body // anonymous interfaces else { // named interfaces and classes - val bodyWithParents = parents.foldLeft(body)((b, p) => s"$b & ${convert(p)}") - if (typeVars.isEmpty) s"$typeName: $bodyWithParents$methods" + val constructor = + if (constructorList.isEmpty) "()" + else s"(${constructorList.map(p => s"${convert(p)("")}").reduceLeft((res, p) => s"$res, $p")})" + + val inheritance = + if (parents.isEmpty) constructor + else parents.foldLeft(s"$constructor: ")((b, p) => s"$b${convert(p)}, ").dropRight(2) + if (typeVars.isEmpty) s"${indent}$typeName$inheritance $body" else - s"$typeName[${typeVars.map((tv) => tv.name).reduceLeft((p, s) => s"$p, $s")}]: $bodyWithParents$methods" // TODO: add constraints + s"${indent}$typeName<${typeVars.map((tv) => tv.name).reduceLeft((p, s) => s"$p, $s")}>$inheritance $body" // TODO: add constraints } } } diff --git a/ts2mls/js/src/main/scala/ts2mls/types/TSType.scala b/ts2mls/js/src/main/scala/ts2mls/types/TSType.scala index f65df790c7..113cc97da7 100644 --- a/ts2mls/js/src/main/scala/ts2mls/types/TSType.scala +++ b/ts2mls/js/src/main/scala/ts2mls/types/TSType.scala @@ -6,13 +6,14 @@ case object Private extends TSAccessModifier case object Protected extends TSAccessModifier sealed abstract class TSType +case class TSParameterType(name: String, val tp: TSType) extends TSType // record both parameter's name and parameter's type case class TSMemberType(val base: TSType, val modifier: TSAccessModifier = Public) extends TSType case class TSTypeParameter(val name: String, constraint: Option[TSType] = None) extends TSType case class TSPrimitiveType(typeName: String) extends TSType case class TSReferenceType(name: String) extends TSType case object TSEnumType extends TSType case class TSTupleType(types: List[TSType]) extends TSType -case class TSFunctionType(params: List[TSType], res: TSType, val typeVars: List[TSTypeParameter]) extends TSType +case class TSFunctionType(params: List[TSParameterType], res: TSType, val typeVars: List[TSTypeParameter]) extends TSType case class TSArrayType(eleType: TSType) extends TSType case class TSSubstitutionType(base: String, applied: List[TSType]) extends TSType @@ -22,6 +23,7 @@ case class TSClassType( statics: Map[String, TSMemberType], typeVars: List[TSTypeParameter], parents: List[TSType], + constructor: List[TSParameterType] ) extends TSType case class TSInterfaceType( diff --git a/ts2mls/js/src/test/diff/Array.d.mls b/ts2mls/js/src/test/diff/Array.d.mls index e3a7165a40..2feabb0aba 100644 --- a/ts2mls/js/src/test/diff/Array.d.mls +++ b/ts2mls/js/src/test/diff/Array.d.mls @@ -1,42 +1,23 @@ -def first: (MutArray[string]) -> (string) -def getZero3: unit -> (MutArray[number]) -def first2: (MutArray[(number) -> (number)]) -> ((number) -> (number)) -def doEs: (MutArray[int]) -> (MutArray[int]) -class C: {} -trait I: { i: number } -def doCs: (MutArray[C]) -> (MutArray[C]) -def doIs: (MutArray[I]) -> (MutArray[I]) -def inter[U, T]: (MutArray[(U) & (T)]) -> (MutArray[(U) & (T)]) -def clean: (MutArray[(string, number, )]) -> (MutArray[(string, number, )]) -def translate[T, U]: (MutArray[T]) -> (MutArray[U]) -def uu: (MutArray[((number) | (false)) | (true)]) -> (MutArray[((number) | (false)) | (true)]) -class Temp[T]: { x: T } -def ta: (MutArray[Temp[(false) | (true)]]) -> (MutArray[Temp[(false) | (true)]]) -def tat[T]: (MutArray[Temp[T]]) -> (MutArray[Temp[T]]) -//│ Defined class C -//│ Defined trait I -//│ Defined class Temp[+T] -//│ first: MutArray[string] -> string -//│ = -//│ getZero3: unit -> MutArray[number] -//│ = -//│ first2: MutArray[number -> number] -> number -> number -//│ = -//│ doEs: MutArray[int] -> MutArray[int] -//│ = -//│ doCs: MutArray[C] -> MutArray[C] -//│ = -//│ doIs: MutArray[I] -> MutArray[I] -//│ = -//│ inter: MutArray['a] -> MutArray['a] -//│ = -//│ clean: MutArray[(string, number,)] -> MutArray[(string, number,)] -//│ = -//│ translate: MutArray['a] -> MutArray['b] -//│ = -//│ uu: MutArray[false | number | true] -> MutArray[false | number | true] -//│ = -//│ ta: MutArray[Temp[bool]] -> MutArray[Temp[bool]] -//│ = -//│ tat: MutArray[Temp['a]] -> MutArray[Temp['a]] -//│ = +:NewParser +:ParseOnly +fun first(x: MutArray): string +fun getZero3(): MutArray +fun first2(fs: MutArray<(number) => number>): (number) => number +fun doEs(e: MutArray): MutArray +class C() {} +trait I() { + let i: number +} +fun doCs(c: MutArray): MutArray +fun doIs(i: MutArray): MutArray +fun inter(x: MutArray<(U) & (T)>): MutArray<(U) & (T)> +fun clean(x: MutArray<(string, number, )>): MutArray<(string, number, )> +fun translate(x: MutArray): MutArray +fun uu(x: MutArray<((number) | (false)) | (true)>): MutArray<((number) | (false)) | (true)> +class Temp() { + let x: T +} +fun ta(ts: MutArray>): MutArray> +fun tat(ts: MutArray>): MutArray> +//│ |#fun| |first|(|x|#:| |MutArray|‹|string|›|)|#:| |string|↵|#fun| |getZero3|(||)|#:| |MutArray|‹|number|›|↵|#fun| |first2|(|fs|#:| |MutArray|‹|(|number|)| |=>| |number|›|)|#:| |(|number|)| |=>| |number|↵|#fun| |doEs|(|e|#:| |MutArray|‹|int|›|)|#:| |MutArray|‹|int|›|↵|#class| |C|(||)| |{||}|↵|#trait| |I|(||)| |{|→|#let| |i|#:| |number|←|↵|}|↵|#fun| |doCs|(|c|#:| |MutArray|‹|C|›|)|#:| |MutArray|‹|C|›|↵|#fun| |doIs|(|i|#:| |MutArray|‹|I|›|)|#:| |MutArray|‹|I|›|↵|#fun| |inter|‹|U|,| |T|›|(|x|#:| |MutArray|‹|(|U|)| |&| |(|T|)|›|)|#:| |MutArray|‹|(|U|)| |&| |(|T|)|›|↵|#fun| |clean|(|x|#:| |MutArray|‹|(|string|,| |number|,| |)|›|)|#:| |MutArray|‹|(|string|,| |number|,| |)|›|↵|#fun| |translate|‹|T|,| |U|›|(|x|#:| |MutArray|‹|T|›|)|#:| |MutArray|‹|U|›|↵|#fun| |uu|(|x|#:| |MutArray|‹|(|(|number|)| ||| |(|false|)|)| ||| |(|true|)|›|)|#:| |MutArray|‹|(|(|number|)| ||| |(|false|)|)| ||| |(|true|)|›|↵|#class| |Temp|‹|T|›|(||)| |{|→|#let| |x|#:| |T|←|↵|}|↵|#fun| |ta|(|ts|#:| |MutArray|‹|Temp|‹|(|false|)| ||| |(|true|)|›|›|)|#:| |MutArray|‹|Temp|‹|(|false|)| ||| |(|true|)|›|›|↵|#fun| |tat|‹|T|›|(|ts|#:| |MutArray|‹|Temp|‹|T|›|›|)|#:| |MutArray|‹|Temp|‹|T|›|›| +//│ Parsed: {fun first: [] -> (x: MutArray[string],) -> string; fun getZero3: [] -> () -> MutArray[number]; fun first2: [] -> (fs: MutArray[number -> number],) -> number -> number; fun doEs: [] -> (e: MutArray[int],) -> MutArray[int]; class C() {}; trait I(): {let i: [] -> number}; fun doCs: [] -> (c: MutArray[C],) -> MutArray[C]; fun doIs: [] -> (i: MutArray[I],) -> MutArray[I]; fun inter: [] -> (x: MutArray[(U,) & (T,)],) -> MutArray[(U,) & (T,)]; fun clean: [] -> (x: MutArray[(string, number,)],) -> MutArray[(string, number,)]; fun translate: [] -> (x: MutArray[T],) -> MutArray[U]; fun uu: [] -> (x: MutArray[((number,) | (false,),) | (true,)],) -> MutArray[((number,) | (false,),) | (true,)]; class Temp[T]() {let x: [] -> T}; fun ta: [] -> (ts: MutArray[Temp[(false,) | (true,)]],) -> MutArray[Temp[(false,) | (true,)]]; fun tat: [] -> (ts: MutArray[Temp[T]],) -> MutArray[Temp[T]]} diff --git a/ts2mls/js/src/test/diff/BasicFunctions.d.mls b/ts2mls/js/src/test/diff/BasicFunctions.d.mls index 4dbb443afc..eaf33b9e39 100644 --- a/ts2mls/js/src/test/diff/BasicFunctions.d.mls +++ b/ts2mls/js/src/test/diff/BasicFunctions.d.mls @@ -1,58 +1,28 @@ -def hello: unit -> (unit) -def add: (number) -> ((number) -> (number)) -def sub: (number) -> ((number) -> (number)) -def foo: unit -> (number) -def id: (anything) -> (anything) -def odd: (number) -> ((false) | (true)) -def isnull: (anything) -> ((false) | (true)) -def bar: unit -> (anything) -def nu: (null) -> (null) -def un: (undefined) -> (undefined) -def fail: unit -> (nothing) -def create: unit -> ({}) -def pa: (number) -> (number) -def wtf: (anything) -> (unit) -class Foooooo: { ooooooo: number } -def inn: (Foooooo) -> (unit) -def out: unit -> (Foooooo) -trait Barrrrrrrrr: { rrrrrrr: number } -def inn2: (Barrrrrrrrr) -> (unit) -def out2: unit -> (Barrrrrrrrr) -//│ Defined class Foooooo -//│ Defined trait Barrrrrrrrr -//│ hello: unit -> unit -//│ = -//│ add: number -> number -> number -//│ = -//│ sub: number -> number -> number -//│ = -//│ foo: unit -> number -//│ = -//│ id: anything -> anything -//│ = -//│ odd: number -> bool -//│ = -//│ isnull: anything -> bool -//│ = -//│ bar: unit -> anything -//│ = -//│ nu: null -> null -//│ = -//│ un: undefined -> undefined -//│ = -//│ fail: unit -> nothing -//│ = -//│ create: unit -> anything -//│ = -//│ pa: number -> number -//│ = -//│ wtf: anything -> unit -//│ = -//│ inn: Foooooo -> unit -//│ = -//│ out: unit -> Foooooo -//│ = -//│ inn2: Barrrrrrrrr -> unit -//│ = -//│ out2: unit -> Barrrrrrrrr -//│ = +:NewParser +:ParseOnly +fun hello(): unit +fun add(x: number, y: number): number +fun sub(x: number, y: number): number +fun foo(): number +fun id(x: anything): anything +fun odd(x: number): (false) | (true) +fun isnull(x: anything): (false) | (true) +fun bar(): anything +fun nu(n: null): null +fun un(n: undefined): undefined +fun fail(): nothing +fun create(): object +fun pa(x: number): number +fun wtf(x: anything): unit +class Foooooo() { + let ooooooo: number +} +fun inn(f: Foooooo): unit +fun out(): Foooooo +trait Barrrrrrrrr() { + let rrrrrrr: number +} +fun inn2(b: Barrrrrrrrr): unit +fun out2(): Barrrrrrrrr +//│ |#fun| |hello|(||)|#:| |unit|↵|#fun| |add|(|x|#:| |number|,| |y|#:| |number|)|#:| |number|↵|#fun| |sub|(|x|#:| |number|,| |y|#:| |number|)|#:| |number|↵|#fun| |foo|(||)|#:| |number|↵|#fun| |id|(|x|#:| |anything|)|#:| |anything|↵|#fun| |odd|(|x|#:| |number|)|#:| |(|false|)| ||| |(|true|)|↵|#fun| |isnull|(|x|#:| |anything|)|#:| |(|false|)| ||| |(|true|)|↵|#fun| |bar|(||)|#:| |anything|↵|#fun| |nu|(|n|#:| |null|)|#:| |null|↵|#fun| |un|(|n|#:| |undefined|)|#:| |undefined|↵|#fun| |fail|(||)|#:| |nothing|↵|#fun| |create|(||)|#:| |object|↵|#fun| |pa|(|x|#:| |number|)|#:| |number|↵|#fun| |wtf|(|x|#:| |anything|)|#:| |unit|↵|#class| |Foooooo|(||)| |{|→|#let| |ooooooo|#:| |number|←|↵|}|↵|#fun| |inn|(|f|#:| |Foooooo|)|#:| |unit|↵|#fun| |out|(||)|#:| |Foooooo|↵|#trait| |Barrrrrrrrr|(||)| |{|→|#let| |rrrrrrr|#:| |number|←|↵|}|↵|#fun| |inn2|(|b|#:| |Barrrrrrrrr|)|#:| |unit|↵|#fun| |out2|(||)|#:| |Barrrrrrrrr| +//│ Parsed: {fun hello: [] -> () -> unit; fun add: [] -> (x: number, y: number,) -> number; fun sub: [] -> (x: number, y: number,) -> number; fun foo: [] -> () -> number; fun id: [] -> (x: anything,) -> anything; fun odd: [] -> (x: number,) -> ((false,) | (true,)); fun isnull: [] -> (x: anything,) -> ((false,) | (true,)); fun bar: [] -> () -> anything; fun nu: [] -> (n: null,) -> null; fun un: [] -> (n: undefined,) -> undefined; fun fail: [] -> () -> nothing; fun create: [] -> () -> object; fun pa: [] -> (x: number,) -> number; fun wtf: [] -> (x: anything,) -> unit; class Foooooo() {let ooooooo: [] -> number}; fun inn: [] -> (f: Foooooo,) -> unit; fun out: [] -> () -> Foooooo; trait Barrrrrrrrr(): {let rrrrrrr: [] -> number}; fun inn2: [] -> (b: Barrrrrrrrr,) -> unit; fun out2: [] -> () -> Barrrrrrrrr} diff --git a/ts2mls/js/src/test/diff/ClassMember.d.mls b/ts2mls/js/src/test/diff/ClassMember.d.mls index f0bfd5bde4..3030acd69a 100644 --- a/ts2mls/js/src/test/diff/ClassMember.d.mls +++ b/ts2mls/js/src/test/diff/ClassMember.d.mls @@ -1,10 +1,25 @@ -class Student: { name: string; isFriend: (Student) -> ((false) | (true)); addScore: (string) -> ((number) -> (unit)); getID: unit -> (number) } -class Foo[T]: { bar: (T) -> (unit) } -class EZ: { inc: (number) -> (number) } -class Outer: {} -class TTT[T]: { ttt: (T) -> (T); ttt2: (T) -> (T) } -//│ Defined class Student -//│ Defined class Foo[-T] -//│ Defined class EZ -//│ Defined class Outer -//│ Defined class TTT[=T] +:NewParser +:ParseOnly +class Student(s: string, age: number) { + let name: string + fun isFriend(other: Student): (false) | (true) + fun addScore(sub: string, score: number): unit + fun getID(): number +} +class Foo() { + fun bar(x: T): unit +} +class EZ() { + fun inc(x: number): number +} +class Outer() { + class Inner() { + let a: number + } +} +class TTT() { + fun ttt(x: T): T + fun ttt2(x: T): T +} +//│ |#class| |Student|(|s|#:| |string|,| |age|#:| |number|)| |{|→|#let| |name|#:| |string|↵|#fun| |isFriend|(|other|#:| |Student|)|#:| |(|false|)| ||| |(|true|)|↵|#fun| |addScore|(|sub|#:| |string|,| |score|#:| |number|)|#:| |unit|↵|#fun| |getID|(||)|#:| |number|←|↵|}|↵|#class| |Foo|‹|T|›|(||)| |{|→|#fun| |bar|(|x|#:| |T|)|#:| |unit|←|↵|}|↵|#class| |EZ|(||)| |{|→|#fun| |inc|(|x|#:| |number|)|#:| |number|←|↵|}|↵|#class| |Outer|(||)| |{|→|#class| |Inner|(||)| |{|→|#let| |a|#:| |number|←|↵|}|←|↵|}|↵|#class| |TTT|‹|T|›|(||)| |{|→|#fun| |ttt|(|x|#:| |T|)|#:| |T|↵|#fun| |ttt2|(|x|#:| |T|)|#:| |T|←|↵|}| +//│ Parsed: {class Student(s: string, age: number,) {let name: [] -> string; fun isFriend: [] -> (other: Student,) -> ((false,) | (true,)); fun addScore: [] -> (sub: string, score: number,) -> unit; fun getID: [] -> () -> number}; class Foo[T]() {fun bar: [] -> (x: T,) -> unit}; class EZ() {fun inc: [] -> (x: number,) -> number}; class Outer() {class Inner() {let a: [] -> number}}; class TTT[T]() {fun ttt: [] -> (x: T,) -> T; fun ttt2: [] -> (x: T,) -> T}} diff --git a/ts2mls/js/src/test/diff/Enum.d.mls b/ts2mls/js/src/test/diff/Enum.d.mls index 61f20a8cda..d7d3e434f1 100644 --- a/ts2mls/js/src/test/diff/Enum.d.mls +++ b/ts2mls/js/src/test/diff/Enum.d.mls @@ -1,9 +1,7 @@ -def pass: (int) -> ((false) | (true)) -def stop: unit -> (int) -def g: (int) -> (int) -//│ pass: int -> bool -//│ = -//│ stop: unit -> int -//│ = -//│ g: int -> int -//│ = +:NewParser +:ParseOnly +fun pass(c: int): (false) | (true) +fun stop(): int +fun g(x: int): int +//│ |#fun| |pass|(|c|#:| |int|)|#:| |(|false|)| ||| |(|true|)|↵|#fun| |stop|(||)|#:| |int|↵|#fun| |g|(|x|#:| |int|)|#:| |int| +//│ Parsed: {fun pass: [] -> (c: int,) -> ((false,) | (true,)); fun stop: [] -> () -> int; fun g: [] -> (x: int,) -> int} diff --git a/ts2mls/js/src/test/diff/Heritage.d.mls b/ts2mls/js/src/test/diff/Heritage.d.mls index 4868aad590..4b45a98f34 100644 --- a/ts2mls/js/src/test/diff/Heritage.d.mls +++ b/ts2mls/js/src/test/diff/Heritage.d.mls @@ -1,30 +1,44 @@ -class A: { foo: unit -> (unit) } -class B: {} & A -class C[T]: { set: (T) -> (unit); get: unit -> (T) } -class D: {} & C[number] -trait Wu: { x: (false) | (true) } -class WuWu: { y: (false) | (true) } & Wu -trait WuWuWu: { z: (false) | (true) } & WuWu -trait Never: { w: unit -> (nothing) } & WuWuWu -class VG[T]: { x: T } -class Home[T]: { y: T } & VG[string] -trait O[I]: { xx: (I) -> (I) } -class OR[R]: { xx: (R) -> (R) } & O[R] -class Five'ROTK: { wu: string } -class Five'Y: {} & Five'ROTK -class Y: {} & Five'ROTK -//│ Defined class A -//│ Defined class B -//│ Defined class C[=T] -//│ Defined class D -//│ Defined trait Wu -//│ Defined class WuWu -//│ Defined trait WuWuWu -//│ Defined trait Never -//│ Defined class VG[+T] -//│ Defined class Home[+T] -//│ Defined trait O[=I] -//│ Defined class OR[=R] -//│ Defined class Five'ROTK -//│ Defined class Five'Y -//│ Defined class Y +:NewParser +:ParseOnly +class A() { + fun foo(): unit +} +class B(): A {} +class C() { + fun set(x: T): unit + fun get(): T +} +class D(): C {} +trait Wu() { + let x: (false) | (true) +} +class WuWu(): Wu { + let y: (false) | (true) +} +trait WuWuWu(): WuWu { + let z: (false) | (true) +} +trait Never(): WuWuWu { + fun w(): nothing +} +class VG() { + let x: T +} +class Home(): VG { + let y: T +} +trait O() { + fun xx(x: I): I +} +class OR(): O { + fun xx(x: R): R +} +namespace Five { + class ROTK() { + let wu: string + } + class Y(): Five'ROTK {} +} +class Y(): Five'ROTK {} +//│ |#class| |A|(||)| |{|→|#fun| |foo|(||)|#:| |unit|←|↵|}|↵|#class| |B|(||)|#:| |A| |{||}|↵|#class| |C|‹|T|›|(||)| |{|→|#fun| |set|(|x|#:| |T|)|#:| |unit|↵|#fun| |get|(||)|#:| |T|←|↵|}|↵|#class| |D|(||)|#:| |C|‹|number|›| |{||}|↵|#trait| |Wu|(||)| |{|→|#let| |x|#:| |(|false|)| ||| |(|true|)|←|↵|}|↵|#class| |WuWu|(||)|#:| |Wu| |{|→|#let| |y|#:| |(|false|)| ||| |(|true|)|←|↵|}|↵|#trait| |WuWuWu|(||)|#:| |WuWu| |{|→|#let| |z|#:| |(|false|)| ||| |(|true|)|←|↵|}|↵|#trait| |Never|(||)|#:| |WuWuWu| |{|→|#fun| |w|(||)|#:| |nothing|←|↵|}|↵|#class| |VG|‹|T|›|(||)| |{|→|#let| |x|#:| |T|←|↵|}|↵|#class| |Home|‹|T|›|(||)|#:| |VG|‹|string|›| |{|→|#let| |y|#:| |T|←|↵|}|↵|#trait| |O|‹|I|›|(||)| |{|→|#fun| |xx|(|x|#:| |I|)|#:| |I|←|↵|}|↵|#class| |OR|‹|R|›|(||)|#:| |O|‹|R|›| |{|→|#fun| |xx|(|x|#:| |R|)|#:| |R|←|↵|}|↵|#namespace| |Five| |{|→|#class| |ROTK|(||)| |{|→|#let| |wu|#:| |string|←|↵|}|↵|#class| |Y|(||)|#:| |Five'ROTK| |{||}|←|↵|}|↵|#class| |Y|(||)|#:| |Five'ROTK| |{||}| +//│ Parsed: {class A() {fun foo: [] -> () -> unit}; class B(): A {}; class C[T]() {fun set: [] -> (x: T,) -> unit; fun get: [] -> () -> T}; class D(): C‹number› {}; trait Wu(): {let x: [] -> (false,) | (true,)}; class WuWu(): Wu {let y: [] -> (false,) | (true,)}; trait WuWuWu(): WuWu: {let z: [] -> (false,) | (true,)}; trait Never(): WuWuWu: {fun w: [] -> () -> nothing}; class VG[T]() {let x: [] -> T}; class Home[T](): VG‹string› {let y: [] -> T}; trait O[I](): {fun xx: [] -> (x: I,) -> I}; class OR[R](): O‹R› {fun xx: [] -> (x: R,) -> R}; namespace Five(): {class ROTK() {let wu: [] -> string}; class Y(): Five'ROTK {}}; class Y(): Five'ROTK {}} diff --git a/ts2mls/js/src/test/diff/HighOrderFunc.d.mls b/ts2mls/js/src/test/diff/HighOrderFunc.d.mls index 217d49e40d..83d941c6a2 100644 --- a/ts2mls/js/src/test/diff/HighOrderFunc.d.mls +++ b/ts2mls/js/src/test/diff/HighOrderFunc.d.mls @@ -1,9 +1,7 @@ -def h1: ((number) -> (number)) -> ((number) -> (number)) -def h2: (string) -> (unit -> (string)) -def h3: ((number) -> (number)) -> (((number) -> (number)) -> ((number) -> (number))) -//│ h1: (number -> number) -> number -> number -//│ = -//│ h2: string -> unit -> string -//│ = -//│ h3: (number -> number) -> (number -> number) -> number -> number -//│ = +:NewParser +:ParseOnly +fun h1(inc: (number) => number, num: number): number +fun h2(hint: string): unit => string +fun h3(f: (number) => number, g: (number) => number): (number) => number +//│ |#fun| |h1|(|inc|#:| |(|number|)| |=>| |number|,| |num|#:| |number|)|#:| |number|↵|#fun| |h2|(|hint|#:| |string|)|#:| |unit| |=>| |string|↵|#fun| |h3|(|f|#:| |(|number|)| |=>| |number|,| |g|#:| |(|number|)| |=>| |number|)|#:| |(|number|)| |=>| |number| +//│ Parsed: {fun h1: [] -> (inc: number -> number, num: number,) -> number; fun h2: [] -> (hint: string,) -> unit -> string; fun h3: [] -> (f: number -> number, g: number -> number,) -> number -> number} diff --git a/ts2mls/js/src/test/diff/InterfaceMember.d.mls b/ts2mls/js/src/test/diff/InterfaceMember.d.mls index c476a64b73..aebb04425e 100644 --- a/ts2mls/js/src/test/diff/InterfaceMember.d.mls +++ b/ts2mls/js/src/test/diff/InterfaceMember.d.mls @@ -1,26 +1,40 @@ -trait IFoo: { a: string; b: (number) -> (number); c: unit -> ((false) | (true)); d: (string) -> (unit) } -trait II[T]: { test: (T) -> (number) } -def create: unit -> ({ v: number }) -def get: ({ t: string }) -> (string) -trait IEvent: { callback: (unit) -> ((number) -> (unit)) } -trait SearchFunc: { __call: (string) -> ((string) -> ((false) | (true))) } -trait StringArray: { __index: (number) -> (string) } -trait Counter: { __call: (number) -> (string); interval: number; reset: unit -> (unit) } -trait Simple: { a: number; b: ((false) | (true)) -> (string) } -trait Simple2[T]: { abc: T } -trait Next: {} & Simple -trait TTT[T]: { ttt: (T) -> (T) } -//│ Defined trait IFoo -//│ Defined trait II[-T] -//│ Defined trait IEvent -//│ Defined trait SearchFunc -//│ Defined trait StringArray -//│ Defined trait Counter -//│ Defined trait Simple -//│ Defined trait Simple2[+T] -//│ Defined trait Next -//│ Defined trait TTT[=T] -//│ create: unit -> {v: number} -//│ = -//│ get: {t: string} -> string -//│ = +:NewParser +:ParseOnly +trait IFoo() { + let a: string + fun b(x: number): number + fun c(): (false) | (true) + fun d(x: string): unit +} +trait II() { + fun test(x: T): number +} +fun create(): (v: number,) +fun get(x: (t: string,)): string +trait IEvent() { + fun callback(): (number) => unit +} +trait SearchFunc() { + fun __call(source: string, subString: string): (false) | (true) +} +trait StringArray() { + fun __index(index: number): string +} +trait Counter() { + fun __call(start: number): string + let interval: number + fun reset(): unit +} +trait Simple() { + let a: number + fun b(x: (false) | (true)): string +} +trait Simple2() { + let abc: T +} +trait Next(): Simple {} +trait TTT() { + fun ttt(x: T): T +} +//│ |#trait| |IFoo|(||)| |{|→|#let| |a|#:| |string|↵|#fun| |b|(|x|#:| |number|)|#:| |number|↵|#fun| |c|(||)|#:| |(|false|)| ||| |(|true|)|↵|#fun| |d|(|x|#:| |string|)|#:| |unit|←|↵|}|↵|#trait| |II|‹|T|›|(||)| |{|→|#fun| |test|(|x|#:| |T|)|#:| |number|←|↵|}|↵|#fun| |create|(||)|#:| |(|v|#:| |number|,|)|↵|#fun| |get|(|x|#:| |(|t|#:| |string|,|)|)|#:| |string|↵|#trait| |IEvent|(||)| |{|→|#fun| |callback|(||)|#:| |(|number|)| |=>| |unit|←|↵|}|↵|#trait| |SearchFunc|(||)| |{|→|#fun| |__call|(|source|#:| |string|,| |subString|#:| |string|)|#:| |(|false|)| ||| |(|true|)|←|↵|}|↵|#trait| |StringArray|(||)| |{|→|#fun| |__index|(|index|#:| |number|)|#:| |string|←|↵|}|↵|#trait| |Counter|(||)| |{|→|#fun| |__call|(|start|#:| |number|)|#:| |string|↵|#let| |interval|#:| |number|↵|#fun| |reset|(||)|#:| |unit|←|↵|}|↵|#trait| |Simple|(||)| |{|→|#let| |a|#:| |number|↵|#fun| |b|(|x|#:| |(|false|)| ||| |(|true|)|)|#:| |string|←|↵|}|↵|#trait| |Simple2|‹|T|›|(||)| |{|→|#let| |abc|#:| |T|←|↵|}|↵|#trait| |Next|(||)|#:| |Simple| |{||}|↵|#trait| |TTT|‹|T|›|(||)| |{|→|#fun| |ttt|(|x|#:| |T|)|#:| |T|←|↵|}| +//│ Parsed: {trait IFoo(): {let a: [] -> string; fun b: [] -> (x: number,) -> number; fun c: [] -> () -> ((false,) | (true,)); fun d: [] -> (x: string,) -> unit}; trait II[T](): {fun test: [] -> (x: T,) -> number}; fun create: [] -> () -> (v: number,); fun get: [] -> (x: (t: string,),) -> string; trait IEvent(): {fun callback: [] -> () -> number -> unit}; trait SearchFunc(): {fun __call: [] -> (source: string, subString: string,) -> ((false,) | (true,))}; trait StringArray(): {fun __index: [] -> (index: number,) -> string}; trait Counter(): {fun __call: [] -> (start: number,) -> string; let interval: [] -> number; fun reset: [] -> () -> unit}; trait Simple(): {let a: [] -> number; fun b: [] -> (x: (false,) | (true,),) -> string}; trait Simple2[T](): {let abc: [] -> T}; trait Next(): Simple: {}; trait TTT[T](): {fun ttt: [] -> (x: T,) -> T}} diff --git a/ts2mls/js/src/test/diff/Intersection.d.mls b/ts2mls/js/src/test/diff/Intersection.d.mls index 50873e53fa..10181ff2a1 100644 --- a/ts2mls/js/src/test/diff/Intersection.d.mls +++ b/ts2mls/js/src/test/diff/Intersection.d.mls @@ -1,35 +1,21 @@ -def extend[T, U]: (T) -> ((U) -> ((T) & (U))) -def foo[T, U]: ((T) & (U)) -> (unit) -def over: (((number) -> (string)) & (({}) -> (string))) -> (string) -trait IA: { x: number } -trait IB: { y: number } -def iii: ((IA) & (IB)) -> ((IA) & (IB)) -def uu[U, V, T, P]: (((((U) & (T)) | ((U) & (P))) | ((V) & (T))) | ((V) & (P))) -> (((((U) & (T)) | ((U) & (P))) | ((V) & (T))) | ((V) & (P))) -def iiii[U, T, V]: (((U) & (T)) & (V)) -> (((U) & (T)) & (V)) -def arr[U, T]: ((MutArray[U]) & (MutArray[T])) -> ((MutArray[U]) & (MutArray[T])) -def tt[U, T, V]: (((U, T, )) & ((V, V, ))) -> (((U, T, )) & ((V, V, ))) -class A: {} -class B: {} -def inter: ((A) & (B)) -> ((A) & (B)) -//│ Defined trait IA -//│ Defined trait IB -//│ Defined class A -//│ Defined class B -//│ extend: 'a -> 'b -> ('a & 'b) -//│ = -//│ foo: anything -> unit -//│ = -//│ over: (anything -> string) -> string -//│ = -//│ iii: (IA & IB) -> (IA & IB) -//│ = -//│ uu: ('a & 'b | 'c & 'b) -> ('a & 'b | 'c & 'b) -//│ = -//│ iiii: 'a -> 'a -//│ = -//│ arr: MutArray[in 'a | 'b out 'a & 'b] -> MutArray[in 'a | 'b out 'a & 'b] -//│ = -//│ tt: ('a & 'b, 'b & 'c,) -> ('a & 'b, 'b & 'c,) -//│ = -//│ inter: nothing -> nothing -//│ = +:NewParser +:ParseOnly +fun extend(first: T, second: U): (T) & (U) +fun foo(x: (T) & (U)): unit +fun over(f: ((number) => string) & ((object) => string)): string +trait IA() { + let x: number +} +trait IB() { + let y: number +} +fun iii(x: (IA) & (IB)): (IA) & (IB) +fun uu(x: ((((U) & (T)) | ((U) & (P))) | ((V) & (T))) | ((V) & (P))): ((((U) & (T)) | ((U) & (P))) | ((V) & (T))) | ((V) & (P)) +fun iiii(x: ((U) & (T)) & (V)): ((U) & (T)) & (V) +fun arr(a: (MutArray) & (MutArray)): (MutArray) & (MutArray) +fun tt(x: ((U, T, )) & ((V, V, ))): ((U, T, )) & ((V, V, )) +class A() {} +class B() {} +fun inter(c: (A) & (B)): (A) & (B) +//│ |#fun| |extend|‹|T|,| |U|›|(|first|#:| |T|,| |second|#:| |U|)|#:| |(|T|)| |&| |(|U|)|↵|#fun| |foo|‹|T|,| |U|›|(|x|#:| |(|T|)| |&| |(|U|)|)|#:| |unit|↵|#fun| |over|(|f|#:| |(|(|number|)| |=>| |string|)| |&| |(|(|object|)| |=>| |string|)|)|#:| |string|↵|#trait| |IA|(||)| |{|→|#let| |x|#:| |number|←|↵|}|↵|#trait| |IB|(||)| |{|→|#let| |y|#:| |number|←|↵|}|↵|#fun| |iii|(|x|#:| |(|IA|)| |&| |(|IB|)|)|#:| |(|IA|)| |&| |(|IB|)|↵|#fun| |uu|‹|U|,| |V|,| |T|,| |P|›|(|x|#:| |(|(|(|(|U|)| |&| |(|T|)|)| ||| |(|(|U|)| |&| |(|P|)|)|)| ||| |(|(|V|)| |&| |(|T|)|)|)| ||| |(|(|V|)| |&| |(|P|)|)|)|#:| |(|(|(|(|U|)| |&| |(|T|)|)| ||| |(|(|U|)| |&| |(|P|)|)|)| ||| |(|(|V|)| |&| |(|T|)|)|)| ||| |(|(|V|)| |&| |(|P|)|)|↵|#fun| |iiii|‹|U|,| |T|,| |V|›|(|x|#:| |(|(|U|)| |&| |(|T|)|)| |&| |(|V|)|)|#:| |(|(|U|)| |&| |(|T|)|)| |&| |(|V|)|↵|#fun| |arr|‹|U|,| |T|›|(|a|#:| |(|MutArray|‹|U|›|)| |&| |(|MutArray|‹|T|›|)|)|#:| |(|MutArray|‹|U|›|)| |&| |(|MutArray|‹|T|›|)|↵|#fun| |tt|‹|U|,| |T|,| |V|›|(|x|#:| |(|(|U|,| |T|,| |)|)| |&| |(|(|V|,| |V|,| |)|)|)|#:| |(|(|U|,| |T|,| |)|)| |&| |(|(|V|,| |V|,| |)|)|↵|#class| |A|(||)| |{||}|↵|#class| |B|(||)| |{||}|↵|#fun| |inter|(|c|#:| |(|A|)| |&| |(|B|)|)|#:| |(|A|)| |&| |(|B|)| +//│ Parsed: {fun extend: [] -> (first: T, second: U,) -> ((T,) & (U,)); fun foo: [] -> (x: (T,) & (U,),) -> unit; fun over: [] -> (f: (number -> string,) & (object -> string,),) -> string; trait IA(): {let x: [] -> number}; trait IB(): {let y: [] -> number}; fun iii: [] -> (x: (IA,) & (IB,),) -> ((IA,) & (IB,)); fun uu: [] -> (x: ((((U,) & (T,),) | ((U,) & (P,),),) | ((V,) & (T,),),) | ((V,) & (P,),),) -> (((((U,) & (T,),) | ((U,) & (P,),),) | ((V,) & (T,),),) | ((V,) & (P,),)); fun iiii: [] -> (x: ((U,) & (T,),) & (V,),) -> (((U,) & (T,),) & (V,)); fun arr: [] -> (a: (MutArray[U],) & (MutArray[T],),) -> ((MutArray[U],) & (MutArray[T],)); fun tt: [] -> (x: ((U, T,),) & ((V, V,),),) -> (((U, T,),) & ((V, V,),)); class A() {}; class B() {}; fun inter: [] -> (c: (A,) & (B,),) -> ((A,) & (B,))} diff --git a/ts2mls/js/src/test/diff/MultiFiles.d.mls b/ts2mls/js/src/test/diff/MultiFiles.d.mls index 9025e914dc..f5e566f1da 100644 --- a/ts2mls/js/src/test/diff/MultiFiles.d.mls +++ b/ts2mls/js/src/test/diff/MultiFiles.d.mls @@ -1,32 +1,22 @@ -def multi1: (number) -> (number) -def multi3: unit -> (unit) -class Foo: {} & Base -trait AnotherBase: { y: string } -def N'f: unit -> (unit) -def N'g: unit -> (unit) -def N'h: unit -> (unit) -def multi2: (string) -> (string) -def multi4: unit -> (unit) -trait Base: { a: number } -class AnotherFoo: {} & AnotherBase -def multi5: unit -> (unit) -//│ Defined class Foo -//│ Defined trait AnotherBase -//│ Defined trait Base -//│ Defined class AnotherFoo -//│ multi1: number -> number -//│ = -//│ multi3: unit -> unit -//│ = -//│ N'f: unit -> unit -//│ = -//│ N'g: unit -> unit -//│ = -//│ N'h: unit -> unit -//│ = -//│ multi2: string -> string -//│ = -//│ multi4: unit -> unit -//│ = -//│ multi5: unit -> unit -//│ = +:NewParser +:ParseOnly +fun multi1(x: number): number +fun multi3(): unit +class Foo(): Base {} +trait AnotherBase() { + let y: string +} +namespace N { + fun f(): unit + fun g(): unit + fun h(): unit +} +fun multi2(x: string): string +fun multi4(): unit +trait Base() { + let a: number +} +class AnotherFoo(): AnotherBase {} +fun multi5(): unit +//│ |#fun| |multi1|(|x|#:| |number|)|#:| |number|↵|#fun| |multi3|(||)|#:| |unit|↵|#class| |Foo|(||)|#:| |Base| |{||}|↵|#trait| |AnotherBase|(||)| |{|→|#let| |y|#:| |string|←|↵|}|↵|#namespace| |N| |{|→|#fun| |f|(||)|#:| |unit|↵|#fun| |g|(||)|#:| |unit|↵|#fun| |h|(||)|#:| |unit|←|↵|}|↵|#fun| |multi2|(|x|#:| |string|)|#:| |string|↵|#fun| |multi4|(||)|#:| |unit|↵|#trait| |Base|(||)| |{|→|#let| |a|#:| |number|←|↵|}|↵|#class| |AnotherFoo|(||)|#:| |AnotherBase| |{||}|↵|#fun| |multi5|(||)|#:| |unit| +//│ Parsed: {fun multi1: [] -> (x: number,) -> number; fun multi3: [] -> () -> unit; class Foo(): Base {}; trait AnotherBase(): {let y: [] -> string}; namespace N(): {fun f: [] -> () -> unit; fun g: [] -> () -> unit; fun h: [] -> () -> unit}; fun multi2: [] -> (x: string,) -> string; fun multi4: [] -> () -> unit; trait Base(): {let a: [] -> number}; class AnotherFoo(): AnotherBase {}; fun multi5: [] -> () -> unit} diff --git a/ts2mls/js/src/test/diff/Namespace.d.mls b/ts2mls/js/src/test/diff/Namespace.d.mls index ac23adfa06..b70deff220 100644 --- a/ts2mls/js/src/test/diff/Namespace.d.mls +++ b/ts2mls/js/src/test/diff/Namespace.d.mls @@ -1,31 +1,32 @@ -def N1'f: (anything) -> (number) -def N1'ff: (anything) -> (number) -class N1'C: { f: unit -> (unit) } -trait N1'I: { f: unit -> (number) } -def N1'N2'fff: ((false) | (true)) -> (number) -def N1'N2'gg: (N1'C) -> (N1'C) -class N1'N2'BBB: {} & N1'C -def AA'f: (anything) -> (string) -class AA'C: { f: unit -> (unit) } -trait AA'I: { f: unit -> (number) } -def f1: (N1'C) -> (N1'C) -def f2: (AA'C) -> (AA'C) -//│ Defined class N1'C -//│ Defined trait N1'I -//│ Defined class N1'N2'BBB -//│ Defined class AA'C -//│ Defined trait AA'I -//│ N1'f: anything -> number -//│ = -//│ N1'ff: anything -> number -//│ = -//│ N1'N2'fff: bool -> number -//│ = -//│ N1'N2'gg: N1'C -> N1'C -//│ = -//│ AA'f: anything -> string -//│ = -//│ f1: N1'C -> N1'C -//│ = -//│ f2: AA'C -> AA'C -//│ = +:NewParser +:ParseOnly +namespace N1 { + fun f(x: anything): number + fun ff(y: anything): number + class C() { + fun f(): unit + } + trait I() { + fun f(): number + } + namespace N2 { + fun fff(x: (false) | (true)): number + fun gg(c: N1'C): N1'C + class BBB(): N1'C {} + } +} +namespace AA { + fun f(x: anything): string + class C() { + fun f(): unit + } + trait I() { + fun f(): number + } + namespace N2 { + } +} +fun f1(x: N1'C): N1'C +fun f2(x: AA'C): AA'C +//│ |#namespace| |N1| |{|→|#fun| |f|(|x|#:| |anything|)|#:| |number|↵|#fun| |ff|(|y|#:| |anything|)|#:| |number|↵|#class| |C|(||)| |{|→|#fun| |f|(||)|#:| |unit|←|↵|}|↵|#trait| |I|(||)| |{|→|#fun| |f|(||)|#:| |number|←|↵|}|↵|#namespace| |N2| |{|→|#fun| |fff|(|x|#:| |(|false|)| ||| |(|true|)|)|#:| |number|↵|#fun| |gg|(|c|#:| |N1'C|)|#:| |N1'C|↵|#class| |BBB|(||)|#:| |N1'C| |{||}|←|↵|}|←|↵|}|↵|#namespace| |AA| |{|→|#fun| |f|(|x|#:| |anything|)|#:| |string|↵|#class| |C|(||)| |{|→|#fun| |f|(||)|#:| |unit|←|↵|}|↵|#trait| |I|(||)| |{|→|#fun| |f|(||)|#:| |number|←|↵|}|↵|#namespace| |N2| |{|↵|}|←|↵|}|↵|#fun| |f1|(|x|#:| |N1'C|)|#:| |N1'C|↵|#fun| |f2|(|x|#:| |AA'C|)|#:| |AA'C| +//│ Parsed: {namespace N1(): {fun f: [] -> (x: anything,) -> number; fun ff: [] -> (y: anything,) -> number; class C() {fun f: [] -> () -> unit}; trait I(): {fun f: [] -> () -> number}; namespace N2(): {fun fff: [] -> (x: (false,) | (true,),) -> number; fun gg: [] -> (c: N1'C,) -> N1'C; class BBB(): N1'C {}}}; namespace AA(): {fun f: [] -> (x: anything,) -> string; class C() {fun f: [] -> () -> unit}; trait I(): {fun f: [] -> () -> number}; namespace N2(): {}}; fun f1: [] -> (x: N1'C,) -> N1'C; fun f2: [] -> (x: AA'C,) -> AA'C} diff --git a/ts2mls/js/src/test/diff/Optional.d.mls b/ts2mls/js/src/test/diff/Optional.d.mls index 11aa03f0f0..6622dc8fa5 100644 --- a/ts2mls/js/src/test/diff/Optional.d.mls +++ b/ts2mls/js/src/test/diff/Optional.d.mls @@ -1,42 +1,24 @@ -def buildName: (string) -> (((string) | (undefined)) -> (string)) -def buildName2: (string) -> (((string) | (undefined)) -> (string)) -def buildName3: (string) -> ((MutArray[string]) -> (string)) -def buildName4: (string) -> ((MutArray[anything]) -> (string)) -trait SquareConfig: { color: (string) | (undefined); width: (number) | (undefined) } -def did: (number) -> ((((number) -> (number)) | (undefined)) -> (number)) -def getOrElse: ((MutArray[{}]) | (undefined)) -> ({}) -class ABC: {} -def testABC: ((ABC) | (undefined)) -> (unit) -def testSquareConfig: ((SquareConfig) | (undefined)) -> (unit) -def err: (((number, string, )) | (undefined)) -> (unit) -def toStr: ((((number) | (false)) | (true)) | (undefined)) -> (string) -def boo[T, U]: (((T) & (U)) | (undefined)) -> (unit) -class B[T]: { b: T } -def boom: ((B[nothing]) | (undefined)) -> (anything) -//│ Defined trait SquareConfig -//│ Defined class ABC -//│ Defined class B[+T] -//│ buildName: string -> (string | undefined) -> string -//│ = -//│ buildName2: string -> (string | undefined) -> string -//│ = -//│ buildName3: string -> MutArray[string] -> string -//│ = -//│ buildName4: string -> MutArray[anything] -> string -//│ = -//│ did: number -> (number -> number | undefined) -> number -//│ = -//│ getOrElse: (MutArray[anything] | undefined) -> anything -//│ = -//│ testABC: (ABC | undefined) -> unit -//│ = -//│ testSquareConfig: (undefined | SquareConfig) -> unit -//│ = -//│ err: ((number, string,) | undefined) -> unit -//│ = -//│ toStr: (false | number | true | undefined) -> string -//│ = -//│ boo: anything -> unit -//│ = -//│ boom: (B[nothing] | undefined) -> anything -//│ = +:NewParser +:ParseOnly +fun buildName(firstName: string, lastName: (string) | (undefined)): string +fun buildName2(firstName: string, lastName: (string) | (undefined)): string +fun buildName3(firstName: string, lastName: MutArray): string +fun buildName4(firstName: string, lastName: MutArray): string +trait SquareConfig() { + let color: (string) | (undefined) + let width: (number) | (undefined) +} +fun did(x: number, f: ((number) => number) | (undefined)): number +fun getOrElse(arr: (MutArray) | (undefined)): object +class ABC() {} +fun testABC(abc: (ABC) | (undefined)): unit +fun testSquareConfig(conf: (SquareConfig) | (undefined)): unit +fun err(msg: ((number, string, )) | (undefined)): unit +fun toStr(x: (((number) | (false)) | (true)) | (undefined)): string +fun boo(x: ((T) & (U)) | (undefined)): unit +class B() { + let b: T +} +fun boom(b: (B) | (undefined)): anything +//│ |#fun| |buildName|(|firstName|#:| |string|,| |lastName|#:| |(|string|)| ||| |(|undefined|)|)|#:| |string|↵|#fun| |buildName2|(|firstName|#:| |string|,| |lastName|#:| |(|string|)| ||| |(|undefined|)|)|#:| |string|↵|#fun| |buildName3|(|firstName|#:| |string|,| |lastName|#:| |MutArray|‹|string|›|)|#:| |string|↵|#fun| |buildName4|(|firstName|#:| |string|,| |lastName|#:| |MutArray|‹|anything|›|)|#:| |string|↵|#trait| |SquareConfig|(||)| |{|→|#let| |color|#:| |(|string|)| ||| |(|undefined|)|↵|#let| |width|#:| |(|number|)| ||| |(|undefined|)|←|↵|}|↵|#fun| |did|(|x|#:| |number|,| |f|#:| |(|(|number|)| |=>| |number|)| ||| |(|undefined|)|)|#:| |number|↵|#fun| |getOrElse|(|arr|#:| |(|MutArray|‹|object|›|)| ||| |(|undefined|)|)|#:| |object|↵|#class| |ABC|(||)| |{||}|↵|#fun| |testABC|(|abc|#:| |(|ABC|)| ||| |(|undefined|)|)|#:| |unit|↵|#fun| |testSquareConfig|(|conf|#:| |(|SquareConfig|)| ||| |(|undefined|)|)|#:| |unit|↵|#fun| |err|(|msg|#:| |(|(|number|,| |string|,| |)|)| ||| |(|undefined|)|)|#:| |unit|↵|#fun| |toStr|(|x|#:| |(|(|(|number|)| ||| |(|false|)|)| ||| |(|true|)|)| ||| |(|undefined|)|)|#:| |string|↵|#fun| |boo|‹|T|,| |U|›|(|x|#:| |(|(|T|)| |&| |(|U|)|)| ||| |(|undefined|)|)|#:| |unit|↵|#class| |B|‹|T|›|(||)| |{|→|#let| |b|#:| |T|←|↵|}|↵|#fun| |boom|(|b|#:| |(|B|‹|nothing|›|)| ||| |(|undefined|)|)|#:| |anything| +//│ Parsed: {fun buildName: [] -> (firstName: string, lastName: (string,) | (undefined,),) -> string; fun buildName2: [] -> (firstName: string, lastName: (string,) | (undefined,),) -> string; fun buildName3: [] -> (firstName: string, lastName: MutArray[string],) -> string; fun buildName4: [] -> (firstName: string, lastName: MutArray[anything],) -> string; trait SquareConfig(): {let color: [] -> (string,) | (undefined,); let width: [] -> (number,) | (undefined,)}; fun did: [] -> (x: number, f: (number -> number,) | (undefined,),) -> number; fun getOrElse: [] -> (arr: (MutArray[object],) | (undefined,),) -> object; class ABC() {}; fun testABC: [] -> (abc: (ABC,) | (undefined,),) -> unit; fun testSquareConfig: [] -> (conf: (SquareConfig,) | (undefined,),) -> unit; fun err: [] -> (msg: ((number, string,),) | (undefined,),) -> unit; fun toStr: [] -> (x: (((number,) | (false,),) | (true,),) | (undefined,),) -> string; fun boo: [] -> (x: ((T,) & (U,),) | (undefined,),) -> unit; class B[T]() {let b: [] -> T}; fun boom: [] -> (b: (B[nothing],) | (undefined,),) -> anything} diff --git a/ts2mls/js/src/test/diff/Overload.d.mls b/ts2mls/js/src/test/diff/Overload.d.mls index 974ddac99a..0a411a79eb 100644 --- a/ts2mls/js/src/test/diff/Overload.d.mls +++ b/ts2mls/js/src/test/diff/Overload.d.mls @@ -1,47 +1,26 @@ -def f: ((number) -> (string)) & ((string) -> (string)) -class M: { foo: ((number) -> (string)) & ((string) -> (string)) } -def app: (((string) -> (unit)) -> ((number) -> (unit))) & (((string) -> (unit)) -> ((string) -> (unit))) -def create: ((number) -> (unit -> ((false) | (true)))) & (((false) | (true)) -> (unit -> ((false) | (true)))) -def g0: ((MutArray[string]) -> (string)) & ((MutArray[{}]) -> (string)) -def db: ((number) -> (MutArray[number])) & (({}) -> (MutArray[number])) -class N: {} -def id: ((M) -> (unit)) & ((N) -> (unit)) -def tst: (({ z: number }) -> ({ y: string })) & (({ z: (false) | (true) }) -> ({ y: string })) -def op: ((number) -> (((number) | (undefined)) -> (unit))) & ((number) -> ((((false) | (true)) | (undefined)) -> (unit))) -def swap: (((number, string, )) -> ((number, string, ))) & (((string, number, )) -> ((number, string, ))) -def u: ((((number) | (false)) | (true)) -> (string)) & (({}) -> (string)) -def doSome[T, U]: (anything) -> (unit) /* warning: the overload of function doSome is not supported yet. */ -def XX'f[T]: (T) -> ((anything) -> (string)) /* warning: the overload of function f is not supported yet. */ -class WWW: {} - method F[T]: (T) -> (anything) /* warning: the overload of function F is not supported yet. */ -def baz: unit -> (anything) /* warning: the overload of function baz is not supported yet. */ -//│ Defined class M -//│ Defined class N -//│ Defined class WWW -//│ Declared WWW.F: WWW -> anything -> anything -//│ f: (number | string) -> string -//│ = -//│ app: (string -> unit) -> (number | string) -> unit -//│ = -//│ create: (false | number | true) -> unit -> bool -//│ = -//│ g0: MutArray[in string] -> string -//│ = -//│ db: anything -> MutArray[number] -//│ = -//│ id: (M | N) -> unit -//│ = -//│ tst: {z: false | number | true} -> {y: string} -//│ = -//│ op: number -> (false | number | true | undefined) -> unit -//│ = -//│ swap: (number | string, number | string,) -> (number, string,) -//│ = -//│ u: anything -> string -//│ = -//│ doSome: anything -> unit -//│ = -//│ XX'f: anything -> anything -> string -//│ = -//│ baz: unit -> anything -//│ = +:NewParser +:ParseOnly +fun f: ((number) => string) & ((string) => string) +class M() { + let foo: ((number) => string) & ((string) => string) +} +fun app: (((string) => unit) => (number) => unit) & (((string) => unit) => (string) => unit) +fun create: ((number) => unit => (false) | (true)) & (((false) | (true)) => unit => (false) | (true)) +fun g0: ((MutArray) => string) & ((MutArray) => string) +fun db: ((number) => MutArray) & ((object) => MutArray) +class N() {} +fun id: ((M) => unit) & ((N) => unit) +fun tst: (((z: number,)) => (y: string,)) & (((z: (false) | (true),)) => (y: string,)) +fun op: ((number) => ((number) | (undefined)) => unit) & ((number) => (((false) | (true)) | (undefined)) => unit) +fun swap: (((number, string, )) => (number, string, )) & (((string, number, )) => (number, string, )) +fun u: ((((number) | (false)) | (true)) => string) & ((object) => string) +fun doSome(x: anything): unit /* warning: the overload of function doSome is not supported yet. */ +namespace XX { + fun f(x: T, n: anything): string /* warning: the overload of function f is not supported yet. */ +} +class WWW() { + fun F(x: T): anything /* warning: the overload of function F is not supported yet. */ +} +fun baz(): anything /* warning: the overload of function baz is not supported yet. */ +//│ |#fun| |f|#:| |(|(|number|)| |=>| |string|)| |&| |(|(|string|)| |=>| |string|)|↵|#class| |M|(||)| |{|→|#let| |foo|#:| |(|(|number|)| |=>| |string|)| |&| |(|(|string|)| |=>| |string|)|←|↵|}|↵|#fun| |app|#:| |(|(|(|string|)| |=>| |unit|)| |=>| |(|number|)| |=>| |unit|)| |&| |(|(|(|string|)| |=>| |unit|)| |=>| |(|string|)| |=>| |unit|)|↵|#fun| |create|#:| |(|(|number|)| |=>| |unit| |=>| |(|false|)| ||| |(|true|)|)| |&| |(|(|(|false|)| ||| |(|true|)|)| |=>| |unit| |=>| |(|false|)| ||| |(|true|)|)|↵|#fun| |g0|#:| |(|(|MutArray|‹|string|›|)| |=>| |string|)| |&| |(|(|MutArray|‹|object|›|)| |=>| |string|)|↵|#fun| |db|#:| |(|(|number|)| |=>| |MutArray|‹|number|›|)| |&| |(|(|object|)| |=>| |MutArray|‹|number|›|)|↵|#class| |N|(||)| |{||}|↵|#fun| |id|#:| |(|(|M|)| |=>| |unit|)| |&| |(|(|N|)| |=>| |unit|)|↵|#fun| |tst|#:| |(|(|(|z|#:| |number|,|)|)| |=>| |(|y|#:| |string|,|)|)| |&| |(|(|(|z|#:| |(|false|)| ||| |(|true|)|,|)|)| |=>| |(|y|#:| |string|,|)|)|↵|#fun| |op|#:| |(|(|number|)| |=>| |(|(|number|)| ||| |(|undefined|)|)| |=>| |unit|)| |&| |(|(|number|)| |=>| |(|(|(|false|)| ||| |(|true|)|)| ||| |(|undefined|)|)| |=>| |unit|)|↵|#fun| |swap|#:| |(|(|(|number|,| |string|,| |)|)| |=>| |(|number|,| |string|,| |)|)| |&| |(|(|(|string|,| |number|,| |)|)| |=>| |(|number|,| |string|,| |)|)|↵|#fun| |u|#:| |(|(|(|(|number|)| ||| |(|false|)|)| ||| |(|true|)|)| |=>| |string|)| |&| |(|(|object|)| |=>| |string|)|↵|#fun| |doSome|‹|T|,| |U|›|(|x|#:| |anything|)|#:| |unit| |/* warning: the overload of function doSome is not supported yet. */|↵|#namespace| |XX| |{|→|#fun| |f|‹|T|›|(|x|#:| |T|,| |n|#:| |anything|)|#:| |string| |/* warning: the overload of function f is not supported yet. */|←|↵|}|↵|#class| |WWW|(||)| |{|→|#fun| |F|‹|T|›|(|x|#:| |T|)|#:| |anything| |/* warning: the overload of function F is not supported yet. */|←|↵|}|↵|#fun| |baz|(||)|#:| |anything| |/* warning: the overload of function baz is not supported yet. */| +//│ Parsed: {fun f: [] -> (number -> string,) & (string -> string,); class M() {let foo: [] -> (number -> string,) & (string -> string,)}; fun app: [] -> ((string -> unit) -> number -> unit,) & ((string -> unit) -> string -> unit,); fun create: [] -> (number -> unit -> ((false,) | (true,)),) & (((false,) | (true,)) -> unit -> ((false,) | (true,)),); fun g0: [] -> (MutArray[string] -> string,) & (MutArray[object] -> string,); fun db: [] -> (number -> MutArray[number],) & (object -> MutArray[number],); class N() {}; fun id: [] -> (M -> unit,) & (N -> unit,); fun tst: [] -> ((z: number,) -> (y: string,),) & ((z: (false,) | (true,),) -> (y: string,),); fun op: [] -> (number -> ((number,) | (undefined,)) -> unit,) & (number -> (((false,) | (true,),) | (undefined,)) -> unit,); fun swap: [] -> ((number, string,) -> (number, string,),) & ((string, number,) -> (number, string,),); fun u: [] -> ((((number,) | (false,),) | (true,)) -> string,) & (object -> string,); fun doSome: [] -> (x: anything,) -> unit; namespace XX(): {fun f: [] -> (x: T, n: anything,) -> string}; class WWW() {fun F: [] -> (x: T,) -> anything}; fun baz: [] -> () -> anything} diff --git a/ts2mls/js/src/test/diff/Tuple.d.mls b/ts2mls/js/src/test/diff/Tuple.d.mls index be0c3f71ce..42c5b9ac5d 100644 --- a/ts2mls/js/src/test/diff/Tuple.d.mls +++ b/ts2mls/js/src/test/diff/Tuple.d.mls @@ -1,40 +1,20 @@ -def key: ((string, (false) | (true), )) -> (string) -def value: ((string, (false) | (true), )) -> ((false) | (true)) -def third: ((number, number, number, )) -> (number) -def vec2: (number) -> ((number) -> ((number, number, ))) -def twoFunctions: (((number) -> (number), (number) -> (number), )) -> ((number) -> (number)) -def tupleIt: (string) -> ((unit -> (string), )) -def s: ((false) | (true)) -> (((string) | (number), ((number) | (false)) | (true), )) -def s2: (((false) | (true), (string) | (number), )) -> ((string) | (number)) -def ex[T, U]: (T) -> ((U) -> ((T, U, (T) & (U), ))) -def foo[T, U]: (((T) & (U), )) -> (unit) -def conv: ({ y: number }) -> (({ y: number }, { z: string }, )) -class A: { x: number } -class B: {} -def swap: ((A, B, )) -> ((B, A, )) -//│ Defined class A -//│ Defined class B -//│ key: (string, bool,) -> string -//│ = -//│ value: (string, bool,) -> bool -//│ = -//│ third: (number, number, number,) -> number -//│ = -//│ vec2: number -> number -> (number, number,) -//│ = -//│ twoFunctions: (number -> number, number -> number,) -> number -> number -//│ = -//│ tupleIt: string -> (unit -> string,) -//│ = -//│ s: bool -> (number | string, false | number | true,) -//│ = -//│ s2: (bool, number | string,) -> (number | string) -//│ = -//│ ex: 'a -> 'b -> ('a, 'b, 'a & 'b,) -//│ = -//│ foo: anything -> unit -//│ = -//│ conv: {y: number} -> ({y: number}, {z: string},) -//│ = -//│ swap: (A, B,) -> (B, A,) -//│ = +:NewParser +:ParseOnly +fun key(x: (string, (false) | (true), )): string +fun value(x: (string, (false) | (true), )): (false) | (true) +fun third(x: (number, number, number, )): number +fun vec2(x: number, y: number): (number, number, ) +fun twoFunctions(ff: ((number) => number, (number) => number, ), x: number): number +fun tupleIt(x: string): (unit => string, ) +fun s(flag: (false) | (true)): ((string) | (number), ((number) | (false)) | (true), ) +fun s2(t: ((false) | (true), (string) | (number), )): (string) | (number) +fun ex(x: T, y: U): (T, U, (T) & (U), ) +fun foo(x: ((T) & (U), )): unit +fun conv(x: (y: number,)): ((y: number,), (z: string,), ) +class A() { + let x: number +} +class B() {} +fun swap(x: (A, B, )): (B, A, ) +//│ |#fun| |key|(|x|#:| |(|string|,| |(|false|)| ||| |(|true|)|,| |)|)|#:| |string|↵|#fun| |value|(|x|#:| |(|string|,| |(|false|)| ||| |(|true|)|,| |)|)|#:| |(|false|)| ||| |(|true|)|↵|#fun| |third|(|x|#:| |(|number|,| |number|,| |number|,| |)|)|#:| |number|↵|#fun| |vec2|(|x|#:| |number|,| |y|#:| |number|)|#:| |(|number|,| |number|,| |)|↵|#fun| |twoFunctions|(|ff|#:| |(|(|number|)| |=>| |number|,| |(|number|)| |=>| |number|,| |)|,| |x|#:| |number|)|#:| |number|↵|#fun| |tupleIt|(|x|#:| |string|)|#:| |(|unit| |=>| |string|,| |)|↵|#fun| |s|(|flag|#:| |(|false|)| ||| |(|true|)|)|#:| |(|(|string|)| ||| |(|number|)|,| |(|(|number|)| ||| |(|false|)|)| ||| |(|true|)|,| |)|↵|#fun| |s2|(|t|#:| |(|(|false|)| ||| |(|true|)|,| |(|string|)| ||| |(|number|)|,| |)|)|#:| |(|string|)| ||| |(|number|)|↵|#fun| |ex|‹|T|,| |U|›|(|x|#:| |T|,| |y|#:| |U|)|#:| |(|T|,| |U|,| |(|T|)| |&| |(|U|)|,| |)|↵|#fun| |foo|‹|T|,| |U|›|(|x|#:| |(|(|T|)| |&| |(|U|)|,| |)|)|#:| |unit|↵|#fun| |conv|(|x|#:| |(|y|#:| |number|,|)|)|#:| |(|(|y|#:| |number|,|)|,| |(|z|#:| |string|,|)|,| |)|↵|#class| |A|(||)| |{|→|#let| |x|#:| |number|←|↵|}|↵|#class| |B|(||)| |{||}|↵|#fun| |swap|(|x|#:| |(|A|,| |B|,| |)|)|#:| |(|B|,| |A|,| |)| +//│ Parsed: {fun key: [] -> (x: (string, (false,) | (true,),),) -> string; fun value: [] -> (x: (string, (false,) | (true,),),) -> ((false,) | (true,)); fun third: [] -> (x: (number, number, number,),) -> number; fun vec2: [] -> (x: number, y: number,) -> (number, number,); fun twoFunctions: [] -> (ff: (number -> number, number -> number,), x: number,) -> number; fun tupleIt: [] -> (x: string,) -> (unit -> string,); fun s: [] -> (flag: (false,) | (true,),) -> ((string,) | (number,), ((number,) | (false,),) | (true,),); fun s2: [] -> (t: ((false,) | (true,), (string,) | (number,),),) -> ((string,) | (number,)); fun ex: [] -> (x: T, y: U,) -> (T, U, (T,) & (U,),); fun foo: [] -> (x: ((T,) & (U,),),) -> unit; fun conv: [] -> (x: (y: number,),) -> ((y: number,), (z: string,),); class A() {let x: [] -> number}; class B() {}; fun swap: [] -> (x: (A, B,),) -> (B, A,)} diff --git a/ts2mls/js/src/test/diff/TypeParameter.d.mls b/ts2mls/js/src/test/diff/TypeParameter.d.mls index 4521d17195..0c08091550 100644 --- a/ts2mls/js/src/test/diff/TypeParameter.d.mls +++ b/ts2mls/js/src/test/diff/TypeParameter.d.mls @@ -1,38 +1,29 @@ -def inc[T]: (T) -> (number) -class CC[T]: { print: (T) -> (unit) } -def con[U, T]: (T) -> (U) -class Printer[T]: { print: (T) -> (unit) } -def setStringPrinter: (Printer[string]) -> (unit) -def getStringPrinter: unit -> (Printer[string]) -def foo[T]: (Printer[T]) -> ((T) -> (T)) -def foo2[T]: (Printer[T]) -> ((T) -> (T)) -class F[T]: { x: T } - method GG[U]: (U) -> (T) -trait I[T]: { x: T } - method GG[U]: (U) -> (T) -class FFF[T]: { fff: (T) -> (unit) } -def fff: (FFF[string]) -> ((string) -> (unit)) -def getFFF: unit -> (FFF[number]) -//│ Defined class CC[-T] -//│ Defined class Printer[-T] -//│ Defined class F[+T] -//│ Declared F.GG: F['T] -> anything -> 'T -//│ Defined trait I[+T] -//│ Declared I.GG: I['T] -> anything -> 'T -//│ Defined class FFF[-T] -//│ inc: anything -> number -//│ = -//│ con: anything -> nothing -//│ = -//│ setStringPrinter: Printer[string] -> unit -//│ = -//│ getStringPrinter: unit -> Printer[string] -//│ = -//│ foo: Printer['a] -> 'a -> 'a -//│ = -//│ foo2: Printer['a] -> 'a -> 'a -//│ = -//│ fff: FFF[string] -> string -> unit -//│ = -//│ getFFF: unit -> FFF[number] -//│ = +:NewParser +:ParseOnly +fun inc(x: T): number +class CC() { + fun print(s: T): unit +} +fun con(t: T): U +class Printer() { + fun print(t: T): unit +} +fun setStringPrinter(p: Printer): unit +fun getStringPrinter(): Printer +fun foo(p: Printer, x: T): T +fun foo2(p: Printer, x: T): T +class F() { + let x: T + fun GG(y: U): T +} +trait I() { + let x: T + fun GG(y: U): T +} +class FFF() { + fun fff(x: T): unit +} +fun fff(p: FFF, s: string): unit +fun getFFF(): FFF +//│ |#fun| |inc|‹|T|›|(|x|#:| |T|)|#:| |number|↵|#class| |CC|‹|T|›|(||)| |{|→|#fun| |print|(|s|#:| |T|)|#:| |unit|←|↵|}|↵|#fun| |con|‹|U|,| |T|›|(|t|#:| |T|)|#:| |U|↵|#class| |Printer|‹|T|›|(||)| |{|→|#fun| |print|(|t|#:| |T|)|#:| |unit|←|↵|}|↵|#fun| |setStringPrinter|(|p|#:| |Printer|‹|string|›|)|#:| |unit|↵|#fun| |getStringPrinter|(||)|#:| |Printer|‹|string|›|↵|#fun| |foo|‹|T|›|(|p|#:| |Printer|‹|T|›|,| |x|#:| |T|)|#:| |T|↵|#fun| |foo2|‹|T|›|(|p|#:| |Printer|‹|T|›|,| |x|#:| |T|)|#:| |T|↵|#class| |F|‹|T|›|(||)| |{|→|#let| |x|#:| |T|↵|#fun| |GG|‹|U|›|(|y|#:| |U|)|#:| |T|←|↵|}|↵|#trait| |I|‹|T|›|(||)| |{|→|#let| |x|#:| |T|↵|#fun| |GG|‹|U|›|(|y|#:| |U|)|#:| |T|←|↵|}|↵|#class| |FFF|‹|T|›|(||)| |{|→|#fun| |fff|(|x|#:| |T|)|#:| |unit|←|↵|}|↵|#fun| |fff|(|p|#:| |FFF|‹|string|›|,| |s|#:| |string|)|#:| |unit|↵|#fun| |getFFF|(||)|#:| |FFF|‹|number|›| +//│ Parsed: {fun inc: [] -> (x: T,) -> number; class CC[T]() {fun print: [] -> (s: T,) -> unit}; fun con: [] -> (t: T,) -> U; class Printer[T]() {fun print: [] -> (t: T,) -> unit}; fun setStringPrinter: [] -> (p: Printer[string],) -> unit; fun getStringPrinter: [] -> () -> Printer[string]; fun foo: [] -> (p: Printer[T], x: T,) -> T; fun foo2: [] -> (p: Printer[T], x: T,) -> T; class F[T]() {let x: [] -> T; fun GG: [] -> (y: U,) -> T}; trait I[T](): {let x: [] -> T; fun GG: [] -> (y: U,) -> T}; class FFF[T]() {fun fff: [] -> (x: T,) -> unit}; fun fff: [] -> (p: FFF[string], s: string,) -> unit; fun getFFF: [] -> () -> FFF[number]} diff --git a/ts2mls/js/src/test/diff/Union.d.mls b/ts2mls/js/src/test/diff/Union.d.mls index aa07c25cf3..7d1fc49b6e 100644 --- a/ts2mls/js/src/test/diff/Union.d.mls +++ b/ts2mls/js/src/test/diff/Union.d.mls @@ -1,21 +1,11 @@ -def getString: ((((string) | (number)) | (false)) | (true)) -> (string) -def test: ((false) | (true)) -> ((string) | (number)) -def run: (((number) -> (number)) | ((number) -> (string))) -> (anything) -def get: ((MutArray[number]) | (MutArray[string])) -> (unit) -def get2: (((string, string, )) | ((number, string, ))) -> (string) -def typeVar[T, U]: ((T) | (U)) -> ((T) | (U)) -def uuuu: ((((string) | (number)) | (false)) | (true)) -> ((((string) | (number)) | (false)) | (true)) -//│ getString: (false | number | string | true) -> string -//│ = -//│ test: bool -> (number | string) -//│ = -//│ run: (number -> (number | string)) -> anything -//│ = -//│ get: MutArray[out number | string] -> unit -//│ = -//│ get2: (number | string, string,) -> string -//│ = -//│ typeVar: 'a -> 'a -//│ = -//│ uuuu: (false | number | string | true) -> (false | number | string | true) -//│ = +:NewParser +:ParseOnly +fun getString(x: (((string) | (number)) | (false)) | (true)): string +fun test(x: (false) | (true)): (string) | (number) +fun run(f: ((number) => number) | ((number) => string)): anything +fun get(arr: (MutArray) | (MutArray)): unit +fun get2(t: ((string, string, )) | ((number, string, ))): string +fun typeVar(x: (T) | (U)): (T) | (U) +fun uuuu(x: (((string) | (number)) | (false)) | (true)): (((string) | (number)) | (false)) | (true) +//│ |#fun| |getString|(|x|#:| |(|(|(|string|)| ||| |(|number|)|)| ||| |(|false|)|)| ||| |(|true|)|)|#:| |string|↵|#fun| |test|(|x|#:| |(|false|)| ||| |(|true|)|)|#:| |(|string|)| ||| |(|number|)|↵|#fun| |run|(|f|#:| |(|(|number|)| |=>| |number|)| ||| |(|(|number|)| |=>| |string|)|)|#:| |anything|↵|#fun| |get|(|arr|#:| |(|MutArray|‹|number|›|)| ||| |(|MutArray|‹|string|›|)|)|#:| |unit|↵|#fun| |get2|(|t|#:| |(|(|string|,| |string|,| |)|)| ||| |(|(|number|,| |string|,| |)|)|)|#:| |string|↵|#fun| |typeVar|‹|T|,| |U|›|(|x|#:| |(|T|)| ||| |(|U|)|)|#:| |(|T|)| ||| |(|U|)|↵|#fun| |uuuu|(|x|#:| |(|(|(|string|)| ||| |(|number|)|)| ||| |(|false|)|)| ||| |(|true|)|)|#:| |(|(|(|string|)| ||| |(|number|)|)| ||| |(|false|)|)| ||| |(|true|)| +//│ Parsed: {fun getString: [] -> (x: (((string,) | (number,),) | (false,),) | (true,),) -> string; fun test: [] -> (x: (false,) | (true,),) -> ((string,) | (number,)); fun run: [] -> (f: (number -> number,) | (number -> string,),) -> anything; fun get: [] -> (arr: (MutArray[number],) | (MutArray[string],),) -> unit; fun get2: [] -> (t: ((string, string,),) | ((number, string,),),) -> string; fun typeVar: [] -> (x: (T,) | (U,),) -> ((T,) | (U,)); fun uuuu: [] -> (x: (((string,) | (number,),) | (false,),) | (true,),) -> ((((string,) | (number,),) | (false,),) | (true,))} diff --git a/ts2mls/js/src/test/typescript/ClassMember.ts b/ts2mls/js/src/test/typescript/ClassMember.ts index 26d669f166..da45f741b0 100644 --- a/ts2mls/js/src/test/typescript/ClassMember.ts +++ b/ts2mls/js/src/test/typescript/ClassMember.ts @@ -1,7 +1,7 @@ class Student { name: string - constructor() {} + constructor(s: string, age: number) {} getID() { return 114514; }