fix(compiler): Runtime error on compilation exported functions with top types [fixes LNG-218] (#822)

This commit is contained in:
Dima 2023-08-09 15:21:18 +02:00 committed by GitHub
parent d2637976c1
commit ef4b0143ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 1530 additions and 718 deletions

View File

@ -37,13 +37,26 @@ object TypeScriptCommon {
s"{ ${st.fields.map(typeToTs).toNel.map(kv => kv._1 + ": " + kv._2 + ";").toList.mkString(" ")} }"
case st: AbilityType =>
s"{ ${st.fields.map(typeToTs).toNel.map(kv => kv._1 + ": " + kv._2 + ";").toList.mkString(" ")} }"
case st: ScalarType if ScalarType.number(st) => "number"
case ScalarType.bool => "boolean"
case ScalarType.string => "string"
case lt: LiteralType if lt.oneOf.exists(ScalarType.number) => "number"
case lt: LiteralType if lt.oneOf(ScalarType.bool) => "boolean"
case lt: LiteralType if lt.oneOf(ScalarType.string) => "string"
case st: ScalarType => st match {
case st: ScalarType if ScalarType.number(st) => "number"
case ScalarType.bool => "boolean"
case ScalarType.string => "string"
// unreachable
case _ => "any"
}
case lt: LiteralType => lt match {
case lt: LiteralType if lt.oneOf.exists(ScalarType.number) => "number"
case lt: LiteralType if lt.oneOf(ScalarType.bool) => "boolean"
case lt: LiteralType if lt.oneOf(ScalarType.string) => "string"
// unreachable
case _ => "any"
}
case at: ArrowType => fnDef(at)
case TopType => "any"
case BottomType => "nothing"
// impossible. Made to avoid compilation warning
case t: CanonStreamType => "any"
}
// TODO: handle cases if there is already peer_ or config_ variable defined

View File

@ -0,0 +1,25 @@
aqua RenameVars
export rename_s
func append_func(s: *string):
s <<- "ok"
func append(s: string, closure: *string -> ()) -> *string:
status: *string
append_func(status)
closure(status)
<- status
func rename_s() -> []string:
on HOST_PEER_ID:
append_closure = (s: *string):
s <<- "ok"
-- s inside append_func and append_closure
-- are not related to this s and should be
-- renamed to `status` and not `s-<n>`
s = "s"
res <- append(s, append_closure)
<- res

View File

@ -0,0 +1,12 @@
aqua TopBottom
export S, topBottom
-- this file should just compile
service S(""):
top(t: ) ->
bottom(b: ⊥) -> ⊥
func topBottom(t: , b: ⊥) -> , ⊥:
<- S.top(t), S.bottom(b)

File diff suppressed because it is too large Load Diff

View File

@ -41,8 +41,8 @@
},
"dependencies": {
"@fluencelabs/fluence-network-environment": "1.1.2",
"@fluencelabs/js-client.api": "0.12.0",
"@fluencelabs/js-client.node": "0.7.0",
"@fluencelabs/js-client.api": "0.12.1",
"@fluencelabs/js-client.node": "0.7.1",
"deep-equal": "2.2.1",
"loglevel": "1.8.1"
},

View File

@ -51,6 +51,7 @@ import { streamCallbackCall } from '../examples/streamCallback.js';
import { streamResCall } from '../examples/streamRestrictionsCall.js';
import { joinIdxCall, joinIdxLocalCall, joinIdxRelayCall } from '../examples/joinCall.js';
import { recursiveStreamsCall } from '../examples/recursiveStreamsCall.js';
import { renameVarsCall } from '../examples/renameVars.js';
import { arraySugarCall, bugLNG59Call, optionSugarCall, streamSugarCall } from '../examples/collectionSugarCall.js';
import { funcsCall } from '../examples/funcsCall.js';
import { nestedDataCall } from '../examples/nestedDataCall.js';
@ -509,6 +510,11 @@ describe('Testing examples', () => {
// expect(sucList.length).toEqual(5);
// });
it('renameVars.aqua', async () => {
let renameVarsResult = await renameVarsCall();
expect(renameVarsResult).toEqual(['ok', 'ok']);
});
it('callArrow.aqua', async () => {
let callArrowResult = await callArrowCall(relayPeerId1);

View File

@ -0,0 +1,5 @@
import { rename_s } from '../compiled/examples/renameVars.js';
export async function renameVarsCall(): Promise<string[]> {
return await rename_s();
}

View File

@ -4,12 +4,11 @@ import aqua.model
import aqua.model.inline.state.{Arrows, Exports, Mangler}
import aqua.model.*
import aqua.raw.ops.RawTag
import aqua.types.{AbilityType, ArrowType, BoxType, DataType, StreamType, Type}
import aqua.types.{AbilityType, ArrowType, BoxType, StreamType}
import aqua.raw.value.{ValueRaw, VarRaw}
import cats.{Eval, Monoid}
import cats.data.{Chain, IndexedStateT, State}
import cats.syntax.traverse.*
import cats.syntax.apply.*
import cats.syntax.bifunctor.*
import cats.syntax.foldable.*
import scribe.Logging
@ -402,7 +401,10 @@ object ArrowInliner extends Logging {
// Rename all renamed arguments in the body
treeRenamed = fn.body.rename(allShouldRename)
treeStreamsRenamed = renameStreams(treeRenamed, args.streamArgs)
treeStreamsRenamed = renameStreams(
treeRenamed,
args.streamArgs.map { case (k, v) => argsToDataShouldRename.getOrElse(k, k) -> v }
)
// Function body on its own defines some values; collect their names
// except stream arguments. They should be already renamed

View File

@ -1,12 +1,11 @@
package aqua.raw.ops
import aqua.raw.Raw
import aqua.raw.arrow.FuncRaw
import aqua.raw.ops.RawTag.Tree
import aqua.raw.value.{CallArrowRaw, ValueRaw, VarRaw}
import aqua.raw.value.{CallArrowRaw, ValueRaw}
import aqua.tree.{TreeNode, TreeNodeCompanion}
import aqua.types.{ArrowType, DataType, ProductType}
import cats.{Eval, Show}
import aqua.types.{ArrowType, DataType}
import cats.Show
import cats.data.{Chain, NonEmptyList}
import cats.free.Cofree
@ -21,7 +20,7 @@ sealed trait RawTag extends TreeNode[RawTag] {
// All variable names introduced by this tag
def definesVarNames: Set[String] = exportsVarNames ++ restrictsVarNames
def mapValues(f: ValueRaw => ValueRaw): RawTag = this
def mapValues(f: ValueRaw => ValueRaw): RawTag
def renameExports(map: Map[String, String]): RawTag = this
@ -38,7 +37,9 @@ object RawTag extends TreeNodeCompanion[RawTag] with RawTagGivens {
sealed trait NoExecTag extends RawTag
sealed trait GroupTag extends RawTag
sealed trait GroupTag extends RawTag {
override def mapValues(f: ValueRaw => ValueRaw): RawTag = this
}
sealed trait SeqGroupTag extends GroupTag
@ -80,7 +81,10 @@ case object ParTag extends ParGroupTag {
case object Par extends GroupTag
}
case class IfTag(left: ValueRaw, right: ValueRaw, equal: Boolean) extends GroupTag
case class IfTag(left: ValueRaw, right: ValueRaw, equal: Boolean) extends GroupTag {
override def mapValues(f: ValueRaw => ValueRaw): RawTag =
IfTag(left.map(f), right.map(_.map(f)), equal)
}
object IfTag {
@ -119,6 +123,8 @@ case class NextTag(item: String) extends RawTag {
override def renameExports(map: Map[String, String]): RawTag =
copy(item = map.getOrElse(item, item))
override def mapValues(f: ValueRaw => ValueRaw): RawTag = this
}
case class RestrictionTag(name: String, `type`: DataType) extends SeqGroupTag {
@ -243,7 +249,9 @@ case class ReturnTag(
ReturnTag(values.map(_.map(f)))
}
object EmptyTag extends NoExecTag
object EmptyTag extends NoExecTag {
override def mapValues(f: ValueRaw => ValueRaw): RawTag = this
}
case class AbilityIdTag(
value: ValueRaw,

41
pnpm-lock.yaml generated
View File

@ -46,11 +46,11 @@ importers:
specifier: 1.1.2
version: 1.1.2
'@fluencelabs/js-client.api':
specifier: 0.12.0
version: 0.12.0
specifier: 0.12.1
version: 0.12.1
'@fluencelabs/js-client.node':
specifier: 0.7.0
version: 0.7.0(uint8arraylist@2.4.3)
specifier: 0.7.1
version: 0.7.1(uint8arraylist@2.4.3)
deep-equal:
specifier: 2.2.1
version: 2.2.1
@ -527,8 +527,8 @@ packages:
/@fluencelabs/avm@0.35.3:
resolution: {integrity: sha512-Y5mPPCmAUUKc5CDO12IL8mGEreWa7maVdX0MWCAH4+GvfLPFN1FxOMSKRYEtvkyVEL88pc9pd8cm5IRCBkFthg==}
/@fluencelabs/avm@0.40.0:
resolution: {integrity: sha512-DkCht5+Tg8txRlLIXdP/CPKXmvZqWvJk8Nb89r0JmykPelgI2xTlSkKcAtVrNnGIhp0ghS+HXq2KXVYwu2Il1Q==}
/@fluencelabs/avm@0.43.1:
resolution: {integrity: sha512-6tGOMT/2S3ANrqvPLjPUUHgnZCibdIJQH25lsfPN9wBhAcS+0DsYuh1rQWiiJ7xVpps/tuwzFX7gecMmr7hsnQ==}
dev: false
/@fluencelabs/connection@0.2.0(node-fetch@2.6.11):
@ -639,25 +639,25 @@ packages:
resolution: {integrity: sha512-1nBgrTXa0vwloMMw3iJgbkqK23O6y1hM9YAEOwkUcmvvHQG/OPSYtzAenW7djGhNlA4Lk8QIV4bKNn54WIzjdA==}
engines: {node: '>=10', pnpm: '>=3'}
/@fluencelabs/interfaces@0.8.0:
resolution: {integrity: sha512-sJCSANOp+HkrIUdGOUH+lUkuKDhfcufYq/uWLxYLO26hmS+YPLBrbaPnnLwCX+VK3S7r5wm5fkLQTKTSe/Vaog==}
/@fluencelabs/interfaces@0.8.1:
resolution: {integrity: sha512-RVdaBX8HbMLbgLPMwYvPaQ+XPvelNOGgOpsQGoy4Chw2njuj142LwxeQsa4LBWqE24Z7ebUqcjhlCrfrf9Efqg==}
engines: {node: '>=10', pnpm: '>=3'}
dev: false
/@fluencelabs/js-client.api@0.12.0:
resolution: {integrity: sha512-DfYkmhBV3wkYl84CZR/kw8yonW6DMOUOnNC1/plIo7b6edUHJLVFQd9a9WyIjGxgyOLKn5dlkh8cIfYJ75Hwgg==}
/@fluencelabs/js-client.api@0.12.1:
resolution: {integrity: sha512-VbpNQhWwslCLtonnopJP9Ct8qinKhgq/lhVogPsezzWnqugDNFQ7aoTh49f0JTJ+kah1yXsththRspCX7EeAyQ==}
engines: {node: '>=10', pnpm: '>=3'}
dependencies:
'@fluencelabs/interfaces': 0.8.0
'@fluencelabs/interfaces': 0.8.1
dev: false
/@fluencelabs/js-client.node@0.7.0(uint8arraylist@2.4.3):
resolution: {integrity: sha512-9wIpe1fTvlLtgCSOxFs7E/uCRK/fOkmzfYM8gShwVSp7ie+OLN6oPxsv4BWg3xFg3UnVKVb9cW3jf4nzQtkkSA==}
/@fluencelabs/js-client.node@0.7.1(uint8arraylist@2.4.3):
resolution: {integrity: sha512-pFQzomaKChpzkMjT+GxIDnopbkb/C7HBqFalPExp1ijJ4zNS0ezvssnqNYYFLhCmJqP3ww/hawSl7xPrDiwr5g==}
engines: {node: '>=10', pnpm: '>=3'}
dependencies:
'@fluencelabs/avm': 0.40.0
'@fluencelabs/interfaces': 0.8.0
'@fluencelabs/js-peer': 0.9.0(uint8arraylist@2.4.3)
'@fluencelabs/avm': 0.43.1
'@fluencelabs/interfaces': 0.8.1
'@fluencelabs/js-peer': 0.9.1(uint8arraylist@2.4.3)
'@fluencelabs/marine-js': 0.3.45
platform: 1.3.6
transitivePeerDependencies:
@ -667,13 +667,13 @@ packages:
- utf-8-validate
dev: false
/@fluencelabs/js-peer@0.9.0(uint8arraylist@2.4.3):
resolution: {integrity: sha512-B83DyfHDFhor3s7C9GUYekjJthybIRLf6fzYirR6UaHYcVfO4HxDwV3oDWxpcPKTxJ9+sFa0UK5rgqtIFe3yCg==}
/@fluencelabs/js-peer@0.9.1(uint8arraylist@2.4.3):
resolution: {integrity: sha512-ex9yikbdADvieOxts9zP8w/aaIILOUZnztSExlzUo5FGK7QXrfXg0RH9dCS60NaLx6ROIq8A0khC/aBFSyyPrQ==}
engines: {node: '>=10', pnpm: '>=3'}
dependencies:
'@chainsafe/libp2p-noise': 11.0.0
'@fluencelabs/avm': 0.40.0
'@fluencelabs/interfaces': 0.8.0
'@fluencelabs/avm': 0.43.1
'@fluencelabs/interfaces': 0.8.1
'@fluencelabs/marine-js': 0.3.45
'@libp2p/crypto': 1.0.8(uint8arraylist@2.4.3)
'@libp2p/interface-connection': 3.0.8
@ -2887,6 +2887,7 @@ packages:
/esm@3.2.25:
resolution: {integrity: sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==}
engines: {node: '>=6'}
requiresBuild: true
optional: true
/esprima@4.0.1: