diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5a5e483d72..238f823442 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,9 +73,6 @@ jobs: - name: Check license headers run: make check-headers - - name: Check capabilities of dependencies - run: make check-capabilities - lint-json: name: Lint JSON runs-on: ubuntu-latest diff --git a/Makefile b/Makefile index 327d437533..f822d9b20c 100644 --- a/Makefile +++ b/Makefile @@ -121,9 +121,3 @@ release: @(VERSIONED_FILES="version.go \ npm-packages/cadence-parser/package.json" \ bash ./bump-version.sh $(bump)) - -.PHONY: check-capabilities -check-capabilities: - go install github.com/cugu/gocap@v0.1.0 - go mod download - gocap check . diff --git a/go.cap b/go.cap deleted file mode 100644 index be63e43a0e..0000000000 --- a/go.cap +++ /dev/null @@ -1,16 +0,0 @@ -github.com/onflow/cadence () - -github.com/davecgh/go-spew/spew (file) -github.com/k0kubun/pp (file, runtime) -github.com/klauspost/cpuid/v2 (file, runtime) -github.com/mattn/go-colorable (file) -github.com/onflow/cadence/runtime/errors (runtime) -github.com/onflow/cadence/runtime/parser (file) -github.com/onflow/cadence/runtime/pretty (runtime) -github.com/stretchr/testify/assert (runtime, file, network) -github.com/stretchr/testify/require (network) -github.com/texttheater/golang-levenshtein/levenshtein (file) -github.com/zeebo/blake3/internal/consts (file) -golang.org/x/sys/unix (runtime, syscall) -golang.org/x/xerrors (runtime) -github.com/onflow/cadence/runtime/interpreter (runtime) diff --git a/go.mod b/go.mod index 8adeb56bbb..1894bc65d3 100644 --- a/go.mod +++ b/go.mod @@ -3,16 +3,20 @@ module github.com/onflow/cadence go 1.20 require ( - github.com/bits-and-blooms/bitset v1.2.2 - github.com/c-bata/go-prompt v0.2.5 + github.com/bits-and-blooms/bitset v1.5.0 + github.com/bytecodealliance/wasmtime-go/v12 v12.0.0 + github.com/c-bata/go-prompt v0.2.6 + github.com/dave/dst v0.27.2 github.com/fxamacker/cbor/v2 v2.4.1-0.20230228173756-c0c9f774e40c - github.com/go-test/deep v1.0.5 - github.com/google/go-cmp v0.5.9 // indirect + github.com/k0kubun/pp/v3 v3.2.0 + github.com/kr/pretty v0.3.1 github.com/leanovate/gopter v0.2.9 + github.com/logrusorgru/aurora/v4 v4.0.0 github.com/onflow/atree v0.6.1-0.20230711151834-86040b30171f - github.com/rivo/uniseg v0.2.1-0.20211004051800-57c86be7915a - github.com/schollz/progressbar/v3 v3.8.3 + github.com/rivo/uniseg v0.4.4 + github.com/schollz/progressbar/v3 v3.13.1 github.com/stretchr/testify v1.8.4 + github.com/texttheater/golang-levenshtein/levenshtein v0.0.0-20200805054039-cae8b0eaed6c github.com/tidwall/pretty v1.2.1 github.com/turbolent/prettier v0.0.0-20220320183459-661cc755135d go.opentelemetry.io/otel v1.8.0 @@ -24,17 +28,9 @@ require ( golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 ) -require ( - github.com/dave/dst v0.27.2 - github.com/texttheater/golang-levenshtein/levenshtein v0.0.0-20200805054039-cae8b0eaed6c -) - require ( github.com/SaveTheRbtz/mph v0.1.2 - github.com/bytecodealliance/wasmtime-go/v12 v12.0.0 github.com/k0kubun/pp v3.0.1+incompatible - github.com/k0kubun/pp/v3 v3.2.0 - github.com/logrusorgru/aurora/v4 v4.0.0 golang.org/x/exp v0.0.0-20230321023759-10a507213a29 ) @@ -45,17 +41,19 @@ require ( github.com/fxamacker/circlehash v0.3.0 // indirect github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect github.com/klauspost/cpuid/v2 v2.2.0 // indirect + github.com/kr/text v0.2.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect - github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-runewidth v0.0.14 // indirect github.com/mattn/go-tty v0.0.3 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect - github.com/pkg/term v1.1.0 // indirect + github.com/pkg/term v1.2.0-beta.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/zeebo/blake3 v0.2.3 // indirect golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect - golang.org/x/sys v0.2.0 // indirect - golang.org/x/term v0.1.0 // indirect + golang.org/x/sys v0.6.0 // indirect + golang.org/x/term v0.6.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index a9e272b7b5..e4ebeaee32 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,12 @@ github.com/SaveTheRbtz/mph v0.1.2 h1:5l3W496Up+7BNOVJQnJhzcGBh+wWfxWdmPUAkx3WmaM= github.com/SaveTheRbtz/mph v0.1.2/go.mod h1:V4+WtKQPe2+dEA5os1WnGsEB0NR9qgqqgIiSt73+sT4= -github.com/bits-and-blooms/bitset v1.2.2 h1:J5gbX05GpMdBjCvQ9MteIg2KKDExr7DrgK+Yc15FvIk= -github.com/bits-and-blooms/bitset v1.2.2/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD6ZIpQT8= +github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bytecodealliance/wasmtime-go/v12 v12.0.0 h1:Wga02UaZXYF3p0LIeL5xFp09/RI7UhjfT2uB0mLrwlw= github.com/bytecodealliance/wasmtime-go/v12 v12.0.0/go.mod h1:a3PRoftJxxUzkQvgjC6sv7pKyJJK0ZsFVmH+eeEKQC4= -github.com/c-bata/go-prompt v0.2.5 h1:3zg6PecEywxNn0xiqcXHD96fkbxghD+gdB2tbsYfl+Y= -github.com/c-bata/go-prompt v0.2.5/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw= +github.com/c-bata/go-prompt v0.2.6 h1:POP+nrHE+DfLYx370bedwNhsqmpCUynWPxuHi0C5vZI= +github.com/c-bata/go-prompt v0.2.6/go.mod h1:/LMAke8wD2FsNu9EXNdHxNLbd9MedkPnCdfpU9wwHfY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/dave/dst v0.27.2 h1:4Y5VFTkhGLC1oddtNwuxxe36pnyLxMFXT51FOzH8Ekc= github.com/dave/dst v0.27.2/go.mod h1:jHh6EOibnHgcUW3WjKHisiooEkYwqpHLBSX1iOBhEyc= github.com/dave/jennifer v1.5.0 h1:HmgPN93bVDpkQyYbqhCHj5QlgvUkvEOzMyEvKLgCRrg= @@ -16,10 +17,7 @@ github.com/fxamacker/cbor/v2 v2.4.1-0.20230228173756-c0c9f774e40c h1:5tm/Wbs9d9r github.com/fxamacker/cbor/v2 v2.4.1-0.20230228173756-c0c9f774e40c/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/fxamacker/circlehash v0.3.0 h1:XKdvTtIJV9t7DDUtsf0RIpC1OcxZtPbmgIH7ekx28WA= github.com/fxamacker/circlehash v0.3.0/go.mod h1:3aq3OfVvsWtkWMb6A1owjOQFA+TLsD5FgJflnaQwtMM= -github.com/go-test/deep v1.0.5 h1:AKODKU3pDH1RzZzm6YZu77YWtEAq6uh1rLIAQlay2qc= -github.com/go-test/deep v1.0.5/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= @@ -31,9 +29,12 @@ github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuOb github.com/klauspost/cpuid/v2 v2.2.0 h1:4ZexSFt8agMNzNisrsilL6RClWDC5YJnLHNIfTy4iuc= github.com/klauspost/cpuid/v2 v2.2.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/logrusorgru/aurora/v4 v4.0.0 h1:sRjfPpun/63iADiSvGGjgA1cAYegEWMPCJdUpJYn9JA= @@ -45,13 +46,13 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= -github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-tty v0.0.3 h1:5OfyWorkyO7xP52Mq7tB36ajHDG5OHrmBGIS/DtakQI= github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= @@ -59,15 +60,18 @@ github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/onflow/atree v0.6.1-0.20230711151834-86040b30171f h1:Z8/PgTqOgOg02MTRpTBYO2k16FE6z4wEOtaC2WBR9Xo= github.com/onflow/atree v0.6.1-0.20230711151834-86040b30171f/go.mod h1:xvP61FoOs95K7IYdIYRnNcYQGf4nbF/uuJ0tHf4DRuM= -github.com/pkg/term v1.1.0 h1:xIAAdCMh3QIAy+5FrE8Ad8XoDhEU4ufwbaSozViP9kk= -github.com/pkg/term v1.1.0/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/term v1.2.0-beta.2 h1:L3y/h2jkuBVFdWiJvNfYfKmzcCnILw7mJWm2JQuMppw= +github.com/pkg/term v1.2.0-beta.2/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.2.1-0.20211004051800-57c86be7915a h1:s7GrsqeorVkFR1vGmQ6WVL9nup0eyQCC+YVUeSQLH/Q= -github.com/rivo/uniseg v0.2.1-0.20211004051800-57c86be7915a/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/schollz/progressbar/v3 v3.8.3 h1:FnLGl3ewlDUP+YdSwveXBaXs053Mem/du+wr7XSYKl8= -github.com/schollz/progressbar/v3 v3.8.3/go.mod h1:pWnVCjSBZsT2X3nx9HfRdnCDrpbevliMeoEVhStwHko= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/schollz/progressbar/v3 v3.13.1 h1:o8rySDYiQ59Mwzy2FELeHY5ZARXZTVJC7iHD6PEFUiE= +github.com/schollz/progressbar/v3 v3.13.1/go.mod h1:xvrbki8kfT1fzWzBT/UZd9L6GA+jdL7HAgq2RFnO6fQ= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= @@ -97,7 +101,6 @@ go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= @@ -111,7 +114,6 @@ golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -123,23 +125,15 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200918174421-af09f7315aff/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= diff --git a/runtime/capabilitycontrollers_test.go b/runtime/capabilitycontrollers_test.go index f776eefc9e..743859a255 100644 --- a/runtime/capabilitycontrollers_test.go +++ b/runtime/capabilitycontrollers_test.go @@ -2695,3 +2695,186 @@ func TestRuntimeCapabilityBorrowAsInheritedInterface(t *testing.T) { require.NoError(t, err) } + +func TestRuntimeCapabilityControllerOperationAfterDeletion(t *testing.T) { + + t.Parallel() + + type operation struct { + name string + code string + } + + type testCase struct { + name string + setup string + operations []operation + } + + test := func(testCase testCase, operation operation) { + + testName := fmt.Sprintf("%s: %s", testCase.name, operation.name) + + t.Run(testName, func(t *testing.T) { + t.Parallel() + + rt := NewTestInterpreterRuntime() + + tx := []byte(fmt.Sprintf( + ` + transaction { + prepare(signer: auth(Capabilities) &Account) { + %s + %s + } + } + `, + testCase.setup, + operation.code, + )) + + address := common.MustBytesToAddress([]byte{0x1}) + accountIDs := map[common.Address]uint64{} + + runtimeInterface := &TestRuntimeInterface{ + Storage: NewTestLedger(nil, nil), + OnGetSigningAccounts: func() ([]Address, error) { + return []Address{address}, nil + }, + OnEmitEvent: func(event cadence.Event) error { + return nil + }, + OnGenerateAccountID: func(address common.Address) (uint64, error) { + accountID := accountIDs[address] + 1 + accountIDs[address] = accountID + return accountID, nil + }, + } + + nextTransactionLocation := NewTransactionLocationGenerator() + + // Test + + err := rt.ExecuteTransaction( + Script{ + Source: tx, + }, + Context{ + Interface: runtimeInterface, + Location: nextTransactionLocation(), + }, + ) + + require.ErrorContains(t, err, "controller is deleted") + }) + } + + testCases := []testCase{ + { + name: "Storage capability controller", + setup: ` + // Issue capability and get controller + let storageCapabilities = signer.capabilities.storage + let capability = storageCapabilities.issue<&AnyStruct>(/storage/test1) + let controller = storageCapabilities.getController(byCapabilityID: capability.id)! + + // Prepare bound functions + let delete = controller.delete + let tag = controller.tag + let setTag = controller.setTag + let target = controller.target + let retarget = controller.retarget + + // Delete + controller.delete() + `, + operations: []operation{ + // Read + { + name: "get capability", + code: `controller.capability`, + }, + { + name: "get tag", + code: `controller.tag`, + }, + { + name: "get borrow type", + code: `controller.borrowType`, + }, + { + name: "get ID", + code: `controller.capabilityID`, + }, + // Mutate + { + name: "delete", + code: `delete()`, + }, + { + name: "set tag", + code: `setTag("test")`, + }, + { + name: "target", + code: `target()`, + }, + { + name: "retarget", + code: `retarget(/storage/test2)`, + }, + }, + }, + { + name: "Account capability controller", + setup: ` + // Issue capability and get controller + let accountCapabilities = signer.capabilities.account + let capability = accountCapabilities.issue() + let controller = accountCapabilities.getController(byCapabilityID: capability.id)! + + // Prepare bound functions + let delete = controller.delete + let tag = controller.tag + let setTag = controller.setTag + + // Delete + controller.delete() + `, + operations: []operation{ + // Read + { + name: "get capability", + code: `controller.capability`, + }, + { + name: "get tag", + code: `controller.tag`, + }, + { + name: "get borrow type", + code: `controller.borrowType`, + }, + { + name: "get ID", + code: `controller.capabilityID`, + }, + // Mutate + { + name: "delete", + code: `delete()`, + }, + { + name: "set tag", + code: `setTag("test")`, + }, + }, + }, + } + + for _, testCase := range testCases { + for _, operation := range testCase.operations { + test(testCase, operation) + } + } +} diff --git a/runtime/cmd/cmd.go b/runtime/cmd/cmd.go index 43d4152617..ea74f93167 100644 --- a/runtime/cmd/cmd.go +++ b/runtime/cmd/cmd.go @@ -366,6 +366,11 @@ func (*StandardLibraryHandler) RecordContractUpdate(_ common.AddressLocation, _ // NO-OP } +func (h *StandardLibraryHandler) ContractUpdateRecorded(_ common.AddressLocation) bool { + // NO-OP + return false +} + func (*StandardLibraryHandler) InterpretContract( _ common.AddressLocation, _ *interpreter.Program, diff --git a/runtime/common/metering.go b/runtime/common/metering.go index d2fbd180bd..23abced4d3 100644 --- a/runtime/common/metering.go +++ b/runtime/common/metering.go @@ -314,25 +314,28 @@ func atreeNodes(count uint64, elementSize uint) (leafNodeCount uint64, branchNod return } -func newAtreeMemoryUsage(count uint64, elementSize uint, array bool) (MemoryUsage, MemoryUsage) { +func newAtreeArrayMemoryUsage(count uint64, elementSize uint) (MemoryUsage, MemoryUsage) { newLeafNodes, newBranchNodes := atreeNodes(count, elementSize) - if array { - return MemoryUsage{ - Kind: MemoryKindAtreeArrayDataSlab, - Amount: newLeafNodes, - }, MemoryUsage{ - Kind: MemoryKindAtreeArrayMetaDataSlab, - Amount: newBranchNodes, - } - } else { - return MemoryUsage{ - Kind: MemoryKindAtreeMapDataSlab, - Amount: newLeafNodes, - }, MemoryUsage{ - Kind: MemoryKindAtreeMapMetaDataSlab, - Amount: newBranchNodes, - } - } + return MemoryUsage{ + Kind: MemoryKindAtreeArrayDataSlab, + Amount: newLeafNodes, + }, + MemoryUsage{ + Kind: MemoryKindAtreeArrayMetaDataSlab, + Amount: newBranchNodes, + } +} + +func newAtreeMapMemoryUsage(count uint64, elementSize uint) (MemoryUsage, MemoryUsage) { + newLeafNodes, newBranchNodes := atreeNodes(count, elementSize) + return MemoryUsage{ + Kind: MemoryKindAtreeMapDataSlab, + Amount: newLeafNodes, + }, + MemoryUsage{ + Kind: MemoryKindAtreeMapMetaDataSlab, + Amount: newBranchNodes, + } } func NewCadenceArrayMemoryUsages(length int) (MemoryUsage, MemoryUsage) { @@ -364,28 +367,24 @@ func AdditionalAtreeMemoryUsage(originalCount uint64, elementSize uint, array bo } } -func NewArrayMemoryUsages(count uint64, elementSize uint) (MemoryUsage, MemoryUsage, MemoryUsage, MemoryUsage) { - leaves, branches := newAtreeMemoryUsage(count, elementSize, true) - return ArrayValueBaseMemoryUsage, MemoryUsage{ - Kind: MemoryKindAtreeArrayElementOverhead, - Amount: count, - }, leaves, branches -} - -func NewDictionaryMemoryUsages(count uint64, elementSize uint) (MemoryUsage, MemoryUsage, MemoryUsage, MemoryUsage) { - leaves, branches := newAtreeMemoryUsage(count, elementSize, false) - return DictionaryValueBaseMemoryUsage, MemoryUsage{ - Kind: MemoryKindAtreeMapElementOverhead, - Amount: count, - }, leaves, branches +func NewAtreeArrayMemoryUsages(count uint64, elementSize uint) (MemoryUsage, MemoryUsage, MemoryUsage) { + leaves, branches := newAtreeArrayMemoryUsage(count, elementSize) + return MemoryUsage{ + Kind: MemoryKindAtreeArrayElementOverhead, + Amount: count, + }, + leaves, + branches } -func NewCompositeMemoryUsages(count uint64, elementSize uint) (MemoryUsage, MemoryUsage, MemoryUsage, MemoryUsage) { - leaves, branches := newAtreeMemoryUsage(count, elementSize, false) - return CompositeValueBaseMemoryUsage, MemoryUsage{ - Kind: MemoryKindAtreeMapElementOverhead, - Amount: count, - }, leaves, branches +func NewAtreeMapMemoryUsages(count uint64, elementSize uint) (MemoryUsage, MemoryUsage, MemoryUsage) { + leaves, branches := newAtreeMapMemoryUsage(count, elementSize) + return MemoryUsage{ + Kind: MemoryKindAtreeMapElementOverhead, + Amount: count, + }, + leaves, + branches } func NewAtreeMapPreAllocatedElementsMemoryUsage(count uint64, elementSize uint) MemoryUsage { diff --git a/runtime/contract_test.go b/runtime/contract_test.go index 58adf2f463..02a9bb7ece 100644 --- a/runtime/contract_test.go +++ b/runtime/contract_test.go @@ -309,6 +309,8 @@ func TestRuntimeContract(t *testing.T) { ) RequireError(t, err) + require.ErrorContains(t, err, "cannot overwrite existing contract") + // the deployed code should not have been updated, // and no events should have been emitted, // as the deployment should fail @@ -450,6 +452,8 @@ func TestRuntimeContract(t *testing.T) { } else { RequireError(t, err) + require.ErrorContains(t, err, "cannot overwrite existing contract") + require.Empty(t, deployedCode) require.Empty(t, events) require.Empty(t, loggedMessages) @@ -475,9 +479,11 @@ func TestRuntimeContract(t *testing.T) { Location: nextTransactionLocation(), }, ) - require.NoError(t, err) + RequireError(t, err) - require.Equal(t, []byte(tc.code2), deployedCode) + require.ErrorContains(t, err, "cannot overwrite existing contract") + + require.Empty(t, deployedCode) require.Equal(t, []string{ @@ -486,20 +492,18 @@ func TestRuntimeContract(t *testing.T) { `"Test"`, codeArrayString, `nil`, - `"Test"`, - code2ArrayString, - `"Test"`, - code2ArrayString, }, loggedMessages, ) - require.Len(t, events, 2) - assert.EqualValues(t, stdlib.AccountContractRemovedEventType.ID(), events[0].Type().ID()) - assert.EqualValues(t, stdlib.AccountContractAddedEventType.ID(), events[1].Type().ID()) + require.Len(t, events, 1) + assert.EqualValues(t, + stdlib.AccountContractRemovedEventType.ID(), + events[0].Type().ID(), + ) contractValueExists := getContractValueExists() - + // contract still exists (from previous transaction), if not interface if tc.isInterface { require.False(t, contractValueExists) } else { diff --git a/runtime/contract_update_test.go b/runtime/contract_update_test.go index 57f0130760..20c2a8c243 100644 --- a/runtime/contract_update_test.go +++ b/runtime/contract_update_test.go @@ -29,7 +29,7 @@ import ( "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/interpreter" . "github.com/onflow/cadence/runtime/tests/runtime_utils" - "github.com/onflow/cadence/runtime/tests/utils" + . "github.com/onflow/cadence/runtime/tests/utils" ) func TestRuntimeContractUpdateWithDependencies(t *testing.T) { @@ -142,7 +142,7 @@ func TestRuntimeContractUpdateWithDependencies(t *testing.T) { err := runtime.ExecuteTransaction( Script{ - Source: utils.DeploymentTransaction( + Source: DeploymentTransaction( "Foo", []byte(fooContractV1), ), @@ -163,7 +163,7 @@ func TestRuntimeContractUpdateWithDependencies(t *testing.T) { err = runtime.ExecuteTransaction( Script{ - Source: utils.DeploymentTransaction( + Source: DeploymentTransaction( "Bar", []byte(barContractV1), ), @@ -183,7 +183,7 @@ func TestRuntimeContractUpdateWithDependencies(t *testing.T) { signerAccount = common.MustBytesToAddress([]byte{0x1}) err = runtime.ExecuteTransaction( Script{ - Source: utils.UpdateTransaction("Foo", []byte(fooContractV2)), + Source: UpdateTransaction("Foo", []byte(fooContractV2)), }, Context{ Interface: runtimeInterface, @@ -204,7 +204,7 @@ func TestRuntimeContractUpdateWithDependencies(t *testing.T) { err = runtime.ExecuteTransaction( Script{ - Source: utils.UpdateTransaction("Bar", []byte(barContractV2)), + Source: UpdateTransaction("Bar", []byte(barContractV2)), }, Context{ Interface: runtimeInterface, @@ -283,7 +283,7 @@ func TestRuntimeContractUpdateWithPrecedingIdentifiers(t *testing.T) { err := runtime.ExecuteTransaction( Script{ - Source: utils.UpdateTransaction("Foo", []byte(fooContractV2)), + Source: UpdateTransaction("Foo", []byte(fooContractV2)), }, Context{ Interface: runtimeInterface, @@ -293,3 +293,107 @@ func TestRuntimeContractUpdateWithPrecedingIdentifiers(t *testing.T) { require.NoError(t, err) } + +func TestRuntimeInvalidContractRedeploy(t *testing.T) { + + t.Parallel() + + foo1 := []byte(` + access(all) + contract Foo { + + access(all) + resource R { + + access(all) + var x: Int + + init() { + self.x = 0 + } + } + + access(all) + fun createR(): @R { + return <-create R() + } + } + `) + + foo2 := []byte(` + access(all) + contract Foo { + + access(all) + struct R { + access(all) + var x: Int + + init() { + self.x = 0 + } + } + } + `) + + tx := []byte(` + transaction(foo1: String, foo2: String) { + prepare(signer: auth(Contracts) &Account) { + signer.contracts.add(name: "Foo", code: foo1.utf8) + signer.contracts.add(name: "Foo", code: foo2.utf8) + } + } + `) + + runtime := NewTestInterpreterRuntimeWithConfig(Config{ + AtreeValidationEnabled: false, + }) + + address := common.MustBytesToAddress([]byte{0x1}) + + var events []cadence.Event + + runtimeInterface := &TestRuntimeInterface{ + Storage: NewTestLedger(nil, nil), + OnGetSigningAccounts: func() ([]Address, error) { + return []Address{address}, nil + }, + OnGetAccountContractCode: func(location common.AddressLocation) ([]byte, error) { + return nil, nil + }, + OnResolveLocation: NewSingleIdentifierLocationResolver(t), + OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error { + // "delay" + return nil + }, + OnEmitEvent: func(event cadence.Event) error { + events = append(events, event) + return nil + }, + OnDecodeArgument: func(b []byte, t cadence.Type) (value cadence.Value, err error) { + return json.Decode(nil, b) + }, + } + + nextTransactionLocation := NewTransactionLocationGenerator() + + // Deploy + + err := runtime.ExecuteTransaction( + Script{ + Source: tx, + Arguments: encodeArgs( + cadence.String(foo1), + cadence.String(foo2), + ), + }, + Context{ + Interface: runtimeInterface, + Location: nextTransactionLocation(), + }, + ) + + RequireError(t, err) + + require.ErrorContains(t, err, "cannot overwrite existing contract") +} diff --git a/runtime/environment.go b/runtime/environment.go index 821c0aa346..916651947c 100644 --- a/runtime/environment.go +++ b/runtime/environment.go @@ -324,6 +324,10 @@ func (e *interpreterEnvironment) RecordContractUpdate( e.storage.recordContractUpdate(location, contractValue) } +func (e *interpreterEnvironment) ContractUpdateRecorded(location common.AddressLocation) bool { + return e.storage.contractUpdateRecorded(location) +} + func (e *interpreterEnvironment) TemporarilyRecordCode(location common.AddressLocation, code []byte) { e.codesAndPrograms.setCode(location, code) } @@ -800,7 +804,7 @@ func (e *interpreterEnvironment) newInjectedCompositeFieldsHandler() interpreter case common.AddressLocation: address = location.Address default: - panic(errors.NewUnreachableError()) + return nil } addressValue := interpreter.NewAddressValue( diff --git a/runtime/interpreter/interpreter_expression.go b/runtime/interpreter/interpreter_expression.go index b75a1cba59..171695b532 100644 --- a/runtime/interpreter/interpreter_expression.go +++ b/runtime/interpreter/interpreter_expression.go @@ -136,26 +136,53 @@ func (interpreter *Interpreter) valueIndexExpressionGetterSetter(indexExpression }, ) + // Normally, moves of nested resources (e.g `let r <- rs[0]`) are statically rejected. + // + // However, there are cases in which we do allow moves of nested resources: + // + // - In a swap statement (e.g. `rs[0] <-> rs[1]`) + // - In a variable declaration with two values/assignments (e.g. `let r <- rs["foo"] <- nil`) + // + // In both cases we know that a move of the nested resource is immediately followed by a replacement. + // This notion of an expression that moves a nested resource is tracked in the elaboration. + // + // When indexing is a move of a nested resource, we need to remove the key/value from the container. + // However, for some containers, like arrays, the removal influences other values in the container. + // In case of an array, the removal of an element shifts all following elements. + // + // A removal alone would thus result in subsequent code being executed incorrectly. + // For example, in the case where a swap operation through indexing is performed on the same array, + // e.g. `rs[0] <-> rs[1]`, once the first removal was performed, the second operates on a modified container. + // + // Prevent this problem by temporarily writing a placeholder value after the removal. + // Only perform the replacement with a placeholder in the case of a nested resource move. + // We know that in that case the get operation will be followed by a set operation, + // which will replace the temporary placeholder. + isNestedResourceMove := elaboration.IsNestedResourceMoveExpression(indexExpression) + var get func(allowMissing bool) Value + + if isNestedResourceMove { + get = func(_ bool) Value { + value := target.RemoveKey(interpreter, locationRange, transferredIndexingValue) + target.InsertKey(interpreter, locationRange, transferredIndexingValue, placeholder) + return value + } + } else { + get = func(_ bool) Value { + value := target.GetKey(interpreter, locationRange, transferredIndexingValue) + + // If the indexing value is a reference, then return a reference for the resulting value. + return interpreter.maybeGetReference(indexExpression, value) + } + } + return getterSetter{ target: target, - get: func(_ bool) Value { - if isNestedResourceMove { - return target.RemoveKey(interpreter, locationRange, transferredIndexingValue) - } else { - value := target.GetKey(interpreter, locationRange, transferredIndexingValue) - - // If the indexing value is a reference, then return a reference for the resulting value. - return interpreter.maybeGetReference(indexExpression, value) - } - }, + get: get, set: func(value Value) { - if isNestedResourceMove { - target.InsertKey(interpreter, locationRange, transferredIndexingValue, value) - } else { - target.SetKey(interpreter, locationRange, transferredIndexingValue, value) - } + target.SetKey(interpreter, locationRange, transferredIndexingValue, value) }, } } diff --git a/runtime/interpreter/interpreter_statement.go b/runtime/interpreter/interpreter_statement.go index 59d249c796..ca1ea8cedd 100644 --- a/runtime/interpreter/interpreter_statement.go +++ b/runtime/interpreter/interpreter_statement.go @@ -163,8 +163,10 @@ func (interpreter *Interpreter) visitIfStatementWithVariableDeclaration( // If the resource was not moved ou of the container, // its contents get deleted. + getterSetter := interpreter.assignmentGetterSetter(declaration.Value) + const allowMissing = false - value := interpreter.assignmentGetterSetter(declaration.Value).get(allowMissing) + value := getterSetter.get(allowMissing) if value == nil { panic(errors.NewUnreachableError()) } @@ -473,7 +475,7 @@ func (interpreter *Interpreter) VisitRemoveStatement(removeStatement *ast.Remove if attachment.IsResourceKinded(interpreter) { // this attachment is no longer attached to its base, but the `base` variable is still available in the destructor - attachment.setBaseValue(interpreter, base, attachmentBaseAuthorization(interpreter, attachment)) + attachment.setBaseValue(interpreter, base) attachment.Destroy(interpreter, locationRange) } @@ -527,8 +529,10 @@ func (interpreter *Interpreter) visitVariableDeclaration( // If the resource was not moved ou of the container, // its contents get deleted. + getterSetter := interpreter.assignmentGetterSetter(declaration.Value) + const allowMissing = false - result := interpreter.assignmentGetterSetter(declaration.Value).get(allowMissing) + result := getterSetter.get(allowMissing) if result == nil { panic(errors.NewUnreachableError()) } @@ -581,23 +585,32 @@ func (interpreter *Interpreter) VisitAssignmentStatement(assignment *ast.Assignm } func (interpreter *Interpreter) VisitSwapStatement(swap *ast.SwapStatement) StatementResult { + + // Get type information + swapStatementTypes := interpreter.Program.Elaboration.SwapStatementTypes(swap) leftType := swapStatementTypes.LeftType rightType := swapStatementTypes.RightType - const allowMissing = false + // Evaluate the left side (target and key) - // Evaluate the left expression leftGetterSetter := interpreter.assignmentGetterSetter(swap.Left) + + // Evaluate the right side (target and key) + + rightGetterSetter := interpreter.assignmentGetterSetter(swap.Right) + + // Get left and right values + + const allowMissing = false + leftValue := leftGetterSetter.get(allowMissing) interpreter.checkSwapValue(leftValue, swap.Left) - // Evaluate the right expression - rightGetterSetter := interpreter.assignmentGetterSetter(swap.Right) rightValue := rightGetterSetter.get(allowMissing) interpreter.checkSwapValue(rightValue, swap.Right) - // Set right value to left target + // Set right value to left target, // and left value to right target locationRange := LocationRange{ diff --git a/runtime/interpreter/storage.go b/runtime/interpreter/storage.go index a84c967ac9..a252321324 100644 --- a/runtime/interpreter/storage.go +++ b/runtime/interpreter/storage.go @@ -64,17 +64,33 @@ func ConvertStoredValue(gauge common.MemoryGauge, value atree.Value) (Value, err if !ok { panic(errors.NewUnreachableError()) } - return newArrayValueFromConstructor(gauge, staticType, value.Count(), func() *atree.Array { return value }), nil + return newArrayValueFromAtreeArray( + gauge, + staticType, + ArrayElementSize(staticType), + value, + ), nil case *atree.OrderedMap: typeInfo := value.Type() - switch typeInfo := typeInfo.(type) { + switch staticType := typeInfo.(type) { case *DictionaryStaticType: - return newDictionaryValueFromConstructor(gauge, typeInfo, value.Count(), func() *atree.OrderedMap { return value }), nil + return newDictionaryValueFromAtreeMap( + gauge, + staticType, + DictionaryElementSize(staticType), + value, + ), nil + case compositeTypeInfo: - return newCompositeValueFromConstructor(gauge, value.Count(), typeInfo, func() *atree.OrderedMap { return value }), nil + return newCompositeValueFromAtreeMap( + gauge, + staticType, + value, + ), nil + default: - return nil, errors.NewUnexpectedError("invalid ordered map type info: %T", typeInfo) + return nil, errors.NewUnexpectedError("invalid ordered map type info: %T", staticType) } case Value: diff --git a/runtime/interpreter/value.go b/runtime/interpreter/value.go index b80d96da8e..891e827839 100644 --- a/runtime/interpreter/value.go +++ b/runtime/interpreter/value.go @@ -1043,6 +1043,8 @@ var _ ValueIndexableValue = &StringValue{} var _ MemberAccessibleValue = &StringValue{} var _ IterableValue = &StringValue{} +var VarSizedArrayOfStringType = NewVariableSizedStaticType(nil, PrimitiveStaticTypeString) + func (v *StringValue) prepareGraphemes() { if v.graphemes == nil { v.graphemes = uniseg.NewGraphemes(v.Str) @@ -1342,6 +1344,20 @@ func (v *StringValue) GetMember(interpreter *Interpreter, locationRange Location return v.ToLower(invocation.Interpreter) }, ) + + case sema.StringTypeSplitFunctionName: + return NewHostFunctionValue( + interpreter, + sema.StringTypeSplitFunctionType, + func(invocation Invocation) Value { + separator, ok := invocation.Arguments[0].(*StringValue) + if !ok { + panic(errors.NewUnreachableError()) + } + + return v.Split(invocation.Interpreter, invocation.LocationRange, separator.Str) + }, + ) } return nil @@ -1396,6 +1412,35 @@ func (v *StringValue) ToLower(interpreter *Interpreter) *StringValue { ) } +func (v *StringValue) Split(inter *Interpreter, locationRange LocationRange, separator string) Value { + split := strings.Split(v.Str, separator) + + var index int + count := len(split) + + return NewArrayValueWithIterator( + inter, + VarSizedArrayOfStringType, + common.ZeroAddress, + uint64(count), + func() Value { + if index >= count { + return nil + } + + str := split[index] + index++ + return NewStringValue( + inter, + common.NewStringMemoryUsage(len(str)), + func() string { + return str + }, + ) + }, + ) +} + func (v *StringValue) Storable(storage atree.SlabStorage, address atree.Address, maxInlineSize uint64) (atree.Storable, error) { return maybeLargeImmutableStorable(v, storage, address, maxInlineSize) } @@ -1652,14 +1697,11 @@ func NewArrayValueWithIterator( return v } -func newArrayValueFromAtreeValue( - array *atree.Array, - staticType ArrayStaticType, -) *ArrayValue { - return &ArrayValue{ - Type: staticType, - array: array, +func ArrayElementSize(staticType ArrayStaticType) uint { + if staticType == nil { + return 0 } + return staticType.ElementType().elementSize() } func newArrayValueFromConstructor( @@ -1667,20 +1709,38 @@ func newArrayValueFromConstructor( staticType ArrayStaticType, countOverestimate uint64, constructor func() *atree.Array, -) (array *ArrayValue) { - var elementSize uint - if staticType != nil { - elementSize = staticType.ElementType().elementSize() - } - baseUsage, elementUsage, dataSlabs, metaDataSlabs := common.NewArrayMemoryUsages(countOverestimate, elementSize) - common.UseMemory(gauge, baseUsage) +) *ArrayValue { + + elementSize := ArrayElementSize(staticType) + + elementUsage, dataSlabs, metaDataSlabs := + common.NewAtreeArrayMemoryUsages(countOverestimate, elementSize) common.UseMemory(gauge, elementUsage) common.UseMemory(gauge, dataSlabs) common.UseMemory(gauge, metaDataSlabs) - array = newArrayValueFromAtreeValue(constructor(), staticType) - array.elementSize = elementSize - return + return newArrayValueFromAtreeArray( + gauge, + staticType, + elementSize, + constructor(), + ) +} + +func newArrayValueFromAtreeArray( + gauge common.MemoryGauge, + staticType ArrayStaticType, + elementSize uint, + atreeArray *atree.Array, +) *ArrayValue { + + common.UseMemory(gauge, common.ArrayValueBaseMemoryUsage) + + return &ArrayValue{ + Type: staticType, + array: atreeArray, + elementSize: elementSize, + } } var _ Value = &ArrayValue{} @@ -2639,11 +2699,6 @@ func (v *ArrayValue) Transfer( storable atree.Storable, preventTransfer map[atree.StorageID]struct{}, ) Value { - baseUsage, elementUsage, dataSlabs, metaDataSlabs := common.NewArrayMemoryUsages(v.array.Count(), v.elementSize) - common.UseMemory(interpreter, baseUsage) - common.UseMemory(interpreter, elementUsage) - common.UseMemory(interpreter, dataSlabs) - common.UseMemory(interpreter, metaDataSlabs) config := interpreter.SharedState.Config @@ -2651,7 +2706,10 @@ func (v *ArrayValue) Transfer( v.checkInvalidatedResourceUse(interpreter, locationRange) } - interpreter.ReportComputation(common.ComputationKindTransferArrayValue, uint(v.Count())) + interpreter.ReportComputation( + common.ComputationKindTransferArrayValue, + uint(v.Count()), + ) if config.TracingEnabled { startTime := time.Now() @@ -2692,6 +2750,14 @@ func (v *ArrayValue) Transfer( panic(errors.NewExternalError(err)) } + elementUsage, dataSlabs, metaDataSlabs := common.NewAtreeArrayMemoryUsages( + v.array.Count(), + v.elementSize, + ) + common.UseMemory(interpreter, elementUsage) + common.UseMemory(interpreter, dataSlabs) + common.UseMemory(interpreter, metaDataSlabs) + array, err = atree.NewArrayFromBatchData( config.Storage, address, @@ -2716,9 +2782,7 @@ func (v *ArrayValue) Transfer( } if remove { - err = v.array.PopIterate(func(storable atree.Storable) { - interpreter.RemoveReferencedSlab(storable) - }) + err = v.array.PopIterate(interpreter.RemoveReferencedSlab) if err != nil { panic(errors.NewExternalError(err)) } @@ -2751,8 +2815,13 @@ func (v *ArrayValue) Transfer( } if res == nil { - res = newArrayValueFromAtreeValue(array, v.Type) - res.elementSize = v.elementSize + res = newArrayValueFromAtreeArray( + interpreter, + v.Type, + v.elementSize, + array, + ) + res.semaType = v.semaType res.isResourceKinded = v.isResourceKinded res.isDestroyed = v.isDestroyed @@ -2764,46 +2833,48 @@ func (v *ArrayValue) Transfer( func (v *ArrayValue) Clone(interpreter *Interpreter) Value { config := interpreter.SharedState.Config - iterator, err := v.array.Iterator() - if err != nil { - panic(errors.NewExternalError(err)) - } - - baseUsage, elementUsage, dataSlabs, metaDataSlabs := common.NewArrayMemoryUsages(v.array.Count(), v.elementSize) - common.UseMemory(interpreter, baseUsage) - common.UseMemory(interpreter, elementUsage) - common.UseMemory(interpreter, dataSlabs) - common.UseMemory(interpreter, metaDataSlabs) - - array, err := atree.NewArrayFromBatchData( - config.Storage, - v.StorageAddress(), - v.array.Type(), - func() (atree.Value, error) { - value, err := iterator.Next() + array := newArrayValueFromConstructor( + interpreter, + v.Type, + v.array.Count(), + func() *atree.Array { + iterator, err := v.array.Iterator() if err != nil { - return nil, err - } - if value == nil { - return nil, nil + panic(errors.NewExternalError(err)) } - element := MustConvertStoredValue(interpreter, value). - Clone(interpreter) + array, err := atree.NewArrayFromBatchData( + config.Storage, + v.StorageAddress(), + v.array.Type(), + func() (atree.Value, error) { + value, err := iterator.Next() + if err != nil { + return nil, err + } + if value == nil { + return nil, nil + } + + element := MustConvertStoredValue(interpreter, value). + Clone(interpreter) + + return element, nil + }, + ) + if err != nil { + panic(errors.NewExternalError(err)) + } - return element, nil + return array }, ) - if err != nil { - panic(errors.NewExternalError(err)) - } - return &ArrayValue{ - Type: v.Type, - semaType: v.semaType, - isResourceKinded: v.isResourceKinded, - array: array, - isDestroyed: v.isDestroyed, - } + + array.semaType = v.semaType + array.isResourceKinded = v.isResourceKinded + array.isDestroyed = v.isDestroyed + + return array } func (v *ArrayValue) DeepRemove(interpreter *Interpreter) { @@ -16324,30 +16395,40 @@ func NewCompositeValue( return v } -func newCompositeValueFromOrderedMap( - dict *atree.OrderedMap, - typeInfo compositeTypeInfo, -) *CompositeValue { - return &CompositeValue{ - dictionary: dict, - Location: typeInfo.location, - QualifiedIdentifier: typeInfo.qualifiedIdentifier, - Kind: typeInfo.kind, - } -} - func newCompositeValueFromConstructor( gauge common.MemoryGauge, count uint64, typeInfo compositeTypeInfo, constructor func() *atree.OrderedMap, ) *CompositeValue { - baseUse, elementOverhead, dataUse, metaDataUse := common.NewCompositeMemoryUsages(count, 0) - common.UseMemory(gauge, baseUse) + + elementOverhead, dataUse, metaDataUse := + common.NewAtreeMapMemoryUsages(count, 0) common.UseMemory(gauge, elementOverhead) common.UseMemory(gauge, dataUse) common.UseMemory(gauge, metaDataUse) - return newCompositeValueFromOrderedMap(constructor(), typeInfo) + + return newCompositeValueFromAtreeMap( + gauge, + typeInfo, + constructor(), + ) +} + +func newCompositeValueFromAtreeMap( + gauge common.MemoryGauge, + typeInfo compositeTypeInfo, + atreeOrderedMap *atree.OrderedMap, +) *CompositeValue { + + common.UseMemory(gauge, common.CompositeValueBaseMemoryUsage) + + return &CompositeValue{ + dictionary: atreeOrderedMap, + Location: typeInfo.location, + QualifiedIdentifier: typeInfo.qualifiedIdentifier, + Kind: typeInfo.kind, + } } var _ Value = &CompositeValue{} @@ -16468,7 +16549,7 @@ func (v *CompositeValue) Destroy(interpreter *Interpreter, locationRange Locatio // is a necessary pre-requisite for calling any members of the attachment. However, in // the case of a destructor, this is called implicitly, and thus must have its `base` // set manually - attachment.setBaseValue(interpreter, v, attachmentBaseAuthorization(interpreter, attachment)) + attachment.setBaseValue(interpreter, v) attachment.Destroy(interpreter, locationRange) }) @@ -17140,20 +17221,17 @@ func (v *CompositeValue) Transfer( preventTransfer map[atree.StorageID]struct{}, ) Value { - baseUse, elementOverhead, dataUse, metaDataUse := common.NewCompositeMemoryUsages(v.dictionary.Count(), 0) - common.UseMemory(interpreter, baseUse) - common.UseMemory(interpreter, elementOverhead) - common.UseMemory(interpreter, dataUse) - common.UseMemory(interpreter, metaDataUse) - - interpreter.ReportComputation(common.ComputationKindTransferCompositeValue, 1) - config := interpreter.SharedState.Config if config.InvalidatedResourceValidationEnabled { v.checkInvalidatedResourceUse(interpreter, locationRange) } + interpreter.ReportComputation( + common.ComputationKindTransferCompositeValue, + 1, + ) + if config.TracingEnabled { startTime := time.Now() @@ -17201,7 +17279,14 @@ func (v *CompositeValue) Transfer( panic(errors.NewExternalError(err)) } - elementMemoryUse := common.NewAtreeMapPreAllocatedElementsMemoryUsage(v.dictionary.Count(), 0) + elementCount := v.dictionary.Count() + + elementOverhead, dataUse, metaDataUse := common.NewAtreeMapMemoryUsages(elementCount, 0) + common.UseMemory(interpreter, elementOverhead) + common.UseMemory(interpreter, dataUse) + common.UseMemory(interpreter, metaDataUse) + + elementMemoryUse := common.NewAtreeMapPreAllocatedElementsMemoryUsage(elementCount, 0) common.UseMemory(config.MemoryGauge, elementMemoryUse) dictionary, err = atree.NewMapFromBatchData( @@ -17231,7 +17316,7 @@ func (v *CompositeValue) Transfer( if compositeValue, ok := value.(*CompositeValue); ok && compositeValue.Kind == common.CompositeKindAttachment { - compositeValue.setBaseValue(interpreter, v, attachmentBaseAuthorization(interpreter, compositeValue)) + compositeValue.setBaseValue(interpreter, v) } value = value.Transfer( @@ -17293,7 +17378,13 @@ func (v *CompositeValue) Transfer( v.QualifiedIdentifier, v.Kind, ) - res = newCompositeValueFromOrderedMap(dictionary, info) + + res = newCompositeValueFromAtreeMap( + interpreter, + info, + dictionary, + ) + res.InjectedFields = v.InjectedFields res.ComputedFields = v.ComputedFields res.NestedVariables = v.NestedVariables @@ -17341,9 +17432,6 @@ func (v *CompositeValue) Clone(interpreter *Interpreter) Value { config := interpreter.SharedState.Config - elementMemoryUse := common.NewAtreeMapPreAllocatedElementsMemoryUsage(v.dictionary.Count(), 0) - common.UseMemory(config.MemoryGauge, elementMemoryUse) - dictionary, err := atree.NewMapFromBatchData( config.Storage, v.StorageAddress(), @@ -17549,7 +17637,7 @@ func (v *CompositeValue) getBaseValue() *EphemeralReferenceValue { return v.base } -func (v *CompositeValue) setBaseValue(interpreter *Interpreter, base *CompositeValue, authorization Authorization) { +func (v *CompositeValue) setBaseValue(interpreter *Interpreter, base *CompositeValue) { attachmentType, ok := interpreter.MustSemaTypeOfValue(v).(*sema.CompositeType) if !ok { panic(errors.NewUnreachableError()) @@ -17563,6 +17651,7 @@ func (v *CompositeValue) setBaseValue(interpreter *Interpreter, base *CompositeV baseType = ty } + authorization := attachmentBaseAuthorization(interpreter, v) v.base = NewEphemeralReferenceValue(interpreter, authorization, base, baseType) interpreter.trackReferencedResourceKindedValue(base.StorageID(), base) } @@ -17717,6 +17806,7 @@ func (v *CompositeValue) forEachAttachment(interpreter *Interpreter, _ LocationR // attachments is added that takes a `fun (&Attachment): Void` callback, the `f` provided here // should convert the provided attachment value into a reference before passing it to the user // callback + attachment.setBaseValue(interpreter, v) f(attachment) } } @@ -17734,7 +17824,7 @@ func (v *CompositeValue) getTypeKey( } attachmentType := keyType.(*sema.CompositeType) // dynamically set the attachment's base to this composite, but with authorization based on the requested access on that attachment - attachment.setBaseValue(interpreter, v, attachmentBaseAuthorization(interpreter, attachment)) + attachment.setBaseValue(interpreter, v) // Map the entitlements of the accessing reference through the attachment's entitlement map to get the authorization of this reference attachmentReferenceAuth, err := attachmentReferenceAuthorization(interpreter, attachmentType, baseAccess) @@ -17892,14 +17982,13 @@ func NewDictionaryValueWithAddress( return v } -func newDictionaryValueFromOrderedMap( - dict *atree.OrderedMap, - staticType *DictionaryStaticType, -) *DictionaryValue { - return &DictionaryValue{ - Type: staticType, - dictionary: dict, +func DictionaryElementSize(staticType *DictionaryStaticType) uint { + keySize := staticType.KeyType.elementSize() + valueSize := staticType.ValueType.elementSize() + if keySize == 0 || valueSize == 0 { + return 0 } + return keySize + valueSize } func newDictionaryValueWithIterator( @@ -17969,23 +18058,38 @@ func newDictionaryValueFromConstructor( staticType *DictionaryStaticType, count uint64, constructor func() *atree.OrderedMap, -) (dict *DictionaryValue) { +) *DictionaryValue { - keySize := staticType.KeyType.elementSize() - valueSize := staticType.ValueType.elementSize() - var elementSize uint - if keySize != 0 && valueSize != 0 { - elementSize = keySize + valueSize - } - baseUsage, overheadUsage, dataSlabs, metaDataSlabs := common.NewDictionaryMemoryUsages(count, elementSize) - common.UseMemory(gauge, baseUsage) + elementSize := DictionaryElementSize(staticType) + + overheadUsage, dataSlabs, metaDataSlabs := + common.NewAtreeMapMemoryUsages(count, elementSize) common.UseMemory(gauge, overheadUsage) common.UseMemory(gauge, dataSlabs) common.UseMemory(gauge, metaDataSlabs) - dict = newDictionaryValueFromOrderedMap(constructor(), staticType) - dict.elementSize = elementSize - return + return newDictionaryValueFromAtreeMap( + gauge, + staticType, + elementSize, + constructor(), + ) +} + +func newDictionaryValueFromAtreeMap( + gauge common.MemoryGauge, + staticType *DictionaryStaticType, + elementSize uint, + atreeOrderedMap *atree.OrderedMap, +) *DictionaryValue { + + common.UseMemory(gauge, common.DictionaryValueBaseMemoryUsage) + + return &DictionaryValue{ + Type: staticType, + dictionary: atreeOrderedMap, + elementSize: elementSize, + } } var _ Value = &DictionaryValue{} @@ -18304,6 +18408,9 @@ func (v *DictionaryValue) SetKey( case NilValue: _ = v.Remove(interpreter, locationRange, keyValue) + case placeholderValue: + // NO-OP + default: panic(errors.NewUnreachableError()) } @@ -18864,16 +18971,6 @@ func (v *DictionaryValue) Transfer( storable atree.Storable, preventTransfer map[atree.StorageID]struct{}, ) Value { - baseUse, elementOverhead, dataUse, metaDataUse := common.NewDictionaryMemoryUsages( - v.dictionary.Count(), - v.elementSize, - ) - common.UseMemory(interpreter, baseUse) - common.UseMemory(interpreter, elementOverhead) - common.UseMemory(interpreter, dataUse) - common.UseMemory(interpreter, metaDataUse) - - interpreter.ReportComputation(common.ComputationKindTransferDictionaryValue, uint(v.Count())) config := interpreter.SharedState.Config @@ -18881,6 +18978,11 @@ func (v *DictionaryValue) Transfer( v.checkInvalidatedResourceUse(interpreter, locationRange) } + interpreter.ReportComputation( + common.ComputationKindTransferDictionaryValue, + uint(v.Count()), + ) + if config.TracingEnabled { startTime := time.Now() @@ -18923,7 +19025,20 @@ func (v *DictionaryValue) Transfer( panic(errors.NewExternalError(err)) } - elementMemoryUse := common.NewAtreeMapPreAllocatedElementsMemoryUsage(v.dictionary.Count(), v.elementSize) + elementCount := v.dictionary.Count() + + elementOverhead, dataUse, metaDataUse := common.NewAtreeMapMemoryUsages( + elementCount, + v.elementSize, + ) + common.UseMemory(interpreter, elementOverhead) + common.UseMemory(interpreter, dataUse) + common.UseMemory(interpreter, metaDataUse) + + elementMemoryUse := common.NewAtreeMapPreAllocatedElementsMemoryUsage( + elementCount, + v.elementSize, + ) common.UseMemory(config.MemoryGauge, elementMemoryUse) dictionary, err = atree.NewMapFromBatchData( @@ -18994,8 +19109,13 @@ func (v *DictionaryValue) Transfer( } if res == nil { - res = newDictionaryValueFromOrderedMap(dictionary, v.Type) - res.elementSize = v.elementSize + res = newDictionaryValueFromAtreeMap( + interpreter, + v.Type, + v.elementSize, + dictionary, + ) + res.semaType = v.semaType res.isResourceKinded = v.isResourceKinded res.isDestroyed = v.isDestroyed @@ -19015,10 +19135,7 @@ func (v *DictionaryValue) Clone(interpreter *Interpreter) Value { panic(errors.NewExternalError(err)) } - elementMemoryUse := common.NewAtreeMapPreAllocatedElementsMemoryUsage(v.dictionary.Count(), v.elementSize) - common.UseMemory(config.MemoryGauge, elementMemoryUse) - - dictionary, err := atree.NewMapFromBatchData( + orderedMap, err := atree.NewMapFromBatchData( config.Storage, v.StorageAddress(), atree.NewDefaultDigesterBuilder(), @@ -19049,13 +19166,18 @@ func (v *DictionaryValue) Clone(interpreter *Interpreter) Value { panic(errors.NewExternalError(err)) } - return &DictionaryValue{ - Type: v.Type, - semaType: v.semaType, - isResourceKinded: v.isResourceKinded, - dictionary: dictionary, - isDestroyed: v.isDestroyed, - } + dictionary := newDictionaryValueFromAtreeMap( + interpreter, + v.Type, + v.elementSize, + orderedMap, + ) + + dictionary.semaType = v.semaType + dictionary.isResourceKinded = v.isResourceKinded + dictionary.isDestroyed = v.isDestroyed + + return dictionary } func (v *DictionaryValue) DeepRemove(interpreter *Interpreter) { diff --git a/runtime/interpreter/value_accountcapabilitycontroller.go b/runtime/interpreter/value_accountcapabilitycontroller.go index d311266fd0..e281573292 100644 --- a/runtime/interpreter/value_accountcapabilitycontroller.go +++ b/runtime/interpreter/value_accountcapabilitycontroller.go @@ -33,19 +33,22 @@ type AccountCapabilityControllerValue struct { BorrowType *ReferenceStaticType CapabilityID UInt64Value - // tag is locally cached result of GetTag, and not stored. - // It is populated when the field `tag` is read. - tag *StringValue + // deleted indicates if the controller got deleted. Not stored + deleted bool - // Injected functions + // Lazily initialized function values. + // Host functions based on injected functions (see below). + deleteFunction FunctionValue + setTagFunction FunctionValue + + // Injected functions. // Tags are not stored directly inside the controller // to avoid unnecessary storage reads // when the controller is loaded for borrowing/checking - GetCapability func() *CapabilityValue - GetTag func() *StringValue - SetTag func(*StringValue) - DeleteFunction FunctionValue - setTagFunction FunctionValue + GetCapability func(inter *Interpreter) *CapabilityValue + GetTag func(inter *Interpreter) *StringValue + SetTag func(inter *Interpreter, tag *StringValue) + Delete func(inter *Interpreter, locationRange LocationRange) } func NewUnmeteredAccountCapabilityControllerValue( @@ -208,17 +211,27 @@ func (v *AccountCapabilityControllerValue) ChildStorables() []atree.Storable { } } -func (v *AccountCapabilityControllerValue) GetMember(inter *Interpreter, _ LocationRange, name string) Value { +type deletionCheckedFunctionValue struct { + FunctionValue +} + +func (v *AccountCapabilityControllerValue) GetMember(inter *Interpreter, _ LocationRange, name string) (result Value) { + defer func() { + switch typedResult := result.(type) { + case deletionCheckedFunctionValue: + result = typedResult.FunctionValue + case FunctionValue: + panic(errors.NewUnexpectedError("functions need to check deletion. Use newHostFunctionValue")) + } + }() + + // NOTE: check if controller is already deleted + v.checkDeleted() switch name { case sema.AccountCapabilityControllerTypeTagFieldName: - if v.tag == nil { - v.tag = v.GetTag() - if v.tag == nil { - v.tag = EmptyString - } - } - return v.tag + return v.GetTag(inter) + case sema.AccountCapabilityControllerTypeSetTagFunctionName: if v.setTagFunction == nil { v.setTagFunction = v.newSetTagFunction(inter) @@ -231,11 +244,17 @@ func (v *AccountCapabilityControllerValue) GetMember(inter *Interpreter, _ Locat case sema.AccountCapabilityControllerTypeBorrowTypeFieldName: return NewTypeValue(inter, v.BorrowType) + case sema.AccountCapabilityControllerTypeCapabilityFieldName: + return v.GetCapability(inter) + case sema.AccountCapabilityControllerTypeDeleteFunctionName: - return v.DeleteFunction + if v.deleteFunction == nil { + v.deleteFunction = v.newDeleteFunction(inter) + } + return v.deleteFunction - case sema.AccountCapabilityControllerTypeCapabilityFieldName: - return v.GetCapability() + // NOTE: when adding new functions, ensure checkDeleted is called, + // by e.g. using AccountCapabilityControllerValue.newHostFunction } return nil @@ -247,19 +266,21 @@ func (*AccountCapabilityControllerValue) RemoveMember(_ *Interpreter, _ Location } func (v *AccountCapabilityControllerValue) SetMember( - _ *Interpreter, + inter *Interpreter, _ LocationRange, identifier string, value Value, ) bool { + // NOTE: check if controller is already deleted + v.checkDeleted() + switch identifier { case sema.AccountCapabilityControllerTypeTagFieldName: stringValue, ok := value.(*StringValue) if !ok { panic(errors.NewUnreachableError()) } - v.tag = stringValue - v.SetTag(stringValue) + v.SetTag(inter, stringValue) return true } @@ -298,47 +319,67 @@ func (v *AccountCapabilityControllerValue) ReferenceValue( ) } -// SetDeleted sets the controller as deleted, i.e. functions panic from now on -func (v *AccountCapabilityControllerValue) SetDeleted(gauge common.MemoryGauge) { - - raiseError := func() { +// checkDeleted checks if the controller is deleted, +// and panics if it is. +func (v *AccountCapabilityControllerValue) checkDeleted() { + if v.deleted { panic(errors.NewDefaultUserError("controller is deleted")) } +} - v.SetTag = func(s *StringValue) { - raiseError() - } - v.GetTag = func() *StringValue { - raiseError() - return nil - } - - panicHostFunction := func(Invocation) Value { - raiseError() - return nil +func (v *AccountCapabilityControllerValue) newHostFunctionValue( + gauge common.MemoryGauge, + funcType *sema.FunctionType, + f func(invocation Invocation) Value, +) FunctionValue { + return deletionCheckedFunctionValue{ + FunctionValue: NewHostFunctionValue( + gauge, + funcType, + func(invocation Invocation) Value { + // NOTE: check if controller is already deleted + v.checkDeleted() + + return f(invocation) + }, + ), } +} - v.DeleteFunction = NewHostFunctionValue( - gauge, +func (v *AccountCapabilityControllerValue) newDeleteFunction( + inter *Interpreter, +) FunctionValue { + return v.newHostFunctionValue( + inter, sema.AccountCapabilityControllerTypeDeleteFunctionType, - panicHostFunction, + func(invocation Invocation) Value { + inter := invocation.Interpreter + locationRange := invocation.LocationRange + + v.Delete(inter, locationRange) + + v.deleted = true + + return Void + }, ) } func (v *AccountCapabilityControllerValue) newSetTagFunction( inter *Interpreter, -) *HostFunctionValue { - return NewHostFunctionValue( +) FunctionValue { + return v.newHostFunctionValue( inter, sema.AccountCapabilityControllerTypeSetTagFunctionType, func(invocation Invocation) Value { + inter := invocation.Interpreter + newTagValue, ok := invocation.Arguments[0].(*StringValue) if !ok { panic(errors.NewUnreachableError()) } - v.tag = newTagValue - v.SetTag(newTagValue) + v.SetTag(inter, newTagValue) return Void }, diff --git a/runtime/interpreter/value_storagecapabilitycontroller.go b/runtime/interpreter/value_storagecapabilitycontroller.go index ea5fc74571..fa80326bfc 100644 --- a/runtime/interpreter/value_storagecapabilitycontroller.go +++ b/runtime/interpreter/value_storagecapabilitycontroller.go @@ -46,21 +46,25 @@ type StorageCapabilityControllerValue struct { CapabilityID UInt64Value TargetPath PathValue - // tag is locally cached result of GetTag, and not stored. - // It is populated when the field `tag` is read. - tag *StringValue + // deleted indicates if the controller got deleted. Not stored + deleted bool + + // Lazily initialized function values. + // Host functions based on injected functions (see below). + deleteFunction FunctionValue + targetFunction FunctionValue + retargetFunction FunctionValue + setTagFunction FunctionValue // Injected functions. // Tags are not stored directly inside the controller // to avoid unnecessary storage reads // when the controller is loaded for borrowing/checking - GetCapability func() *CapabilityValue - GetTag func() *StringValue - SetTag func(*StringValue) - TargetFunction FunctionValue - RetargetFunction FunctionValue - DeleteFunction FunctionValue - setTagFunction FunctionValue + GetCapability func(inter *Interpreter) *CapabilityValue + GetTag func(inter *Interpreter) *StringValue + SetTag func(inter *Interpreter, tag *StringValue) + Delete func(inter *Interpreter, locationRange LocationRange) + SetTarget func(inter *Interpreter, locationRange LocationRange, target PathValue) } func NewUnmeteredStorageCapabilityControllerValue( @@ -233,17 +237,22 @@ func (v *StorageCapabilityControllerValue) ChildStorables() []atree.Storable { } } -func (v *StorageCapabilityControllerValue) GetMember(inter *Interpreter, _ LocationRange, name string) Value { +func (v *StorageCapabilityControllerValue) GetMember(inter *Interpreter, _ LocationRange, name string) (result Value) { + defer func() { + switch typedResult := result.(type) { + case deletionCheckedFunctionValue: + result = typedResult.FunctionValue + case FunctionValue: + panic(errors.NewUnexpectedError("functions need to check deletion. Use newHostFunctionValue")) + } + }() + + // NOTE: check if controller is already deleted + v.checkDeleted() switch name { case sema.StorageCapabilityControllerTypeTagFieldName: - if v.tag == nil { - v.tag = v.GetTag() - if v.tag == nil { - v.tag = EmptyString - } - } - return v.tag + return v.GetTag(inter) case sema.StorageCapabilityControllerTypeSetTagFunctionName: if v.setTagFunction == nil { @@ -257,17 +266,29 @@ func (v *StorageCapabilityControllerValue) GetMember(inter *Interpreter, _ Locat case sema.StorageCapabilityControllerTypeBorrowTypeFieldName: return NewTypeValue(inter, v.BorrowType) + case sema.StorageCapabilityControllerTypeCapabilityFieldName: + return v.GetCapability(inter) + + case sema.StorageCapabilityControllerTypeDeleteFunctionName: + if v.deleteFunction == nil { + v.deleteFunction = v.newDeleteFunction(inter) + } + return v.deleteFunction + case sema.StorageCapabilityControllerTypeTargetFunctionName: - return v.TargetFunction + if v.targetFunction == nil { + v.targetFunction = v.newTargetFunction(inter) + } + return v.targetFunction case sema.StorageCapabilityControllerTypeRetargetFunctionName: - return v.RetargetFunction - - case sema.StorageCapabilityControllerTypeDeleteFunctionName: - return v.DeleteFunction + if v.retargetFunction == nil { + v.retargetFunction = v.newRetargetFunction(inter) + } + return v.retargetFunction - case sema.StorageCapabilityControllerTypeCapabilityFieldName: - return v.GetCapability() + // NOTE: when adding new functions, ensure checkDeleted is called, + // by e.g. using StorageCapabilityControllerValue.newHostFunction } return nil @@ -279,19 +300,21 @@ func (*StorageCapabilityControllerValue) RemoveMember(_ *Interpreter, _ Location } func (v *StorageCapabilityControllerValue) SetMember( - _ *Interpreter, + inter *Interpreter, _ LocationRange, identifier string, value Value, ) bool { + // NOTE: check if controller is already deleted + v.checkDeleted() + switch identifier { case sema.StorageCapabilityControllerTypeTagFieldName: stringValue, ok := value.(*StringValue) if !ok { panic(errors.NewUnreachableError()) } - v.tag = stringValue - v.SetTag(stringValue) + v.SetTag(inter, stringValue) return true } @@ -320,57 +343,104 @@ func (v *StorageCapabilityControllerValue) ReferenceValue( ) } -// SetDeleted sets the controller as deleted, i.e. functions panic from now on -func (v *StorageCapabilityControllerValue) SetDeleted(gauge common.MemoryGauge) { - - raiseError := func() { +// checkDeleted checks if the controller is deleted, +// and panics if it is. +func (v *StorageCapabilityControllerValue) checkDeleted() { + if v.deleted { panic(errors.NewDefaultUserError("controller is deleted")) } +} - v.SetTag = func(s *StringValue) { - raiseError() - } - v.GetTag = func() *StringValue { - raiseError() - return nil +func (v *StorageCapabilityControllerValue) newHostFunctionValue( + gauge common.MemoryGauge, + funcType *sema.FunctionType, + f func(invocation Invocation) Value, +) FunctionValue { + return deletionCheckedFunctionValue{ + FunctionValue: NewHostFunctionValue( + gauge, + funcType, + func(invocation Invocation) Value { + // NOTE: check if controller is already deleted + v.checkDeleted() + + return f(invocation) + }, + ), } +} - panicHostFunction := func(Invocation) Value { - raiseError() - return nil - } +func (v *StorageCapabilityControllerValue) newDeleteFunction( + inter *Interpreter, +) FunctionValue { + return v.newHostFunctionValue( + inter, + sema.StorageCapabilityControllerTypeDeleteFunctionType, + func(invocation Invocation) Value { + inter := invocation.Interpreter + locationRange := invocation.LocationRange - v.TargetFunction = NewHostFunctionValue( - gauge, + v.Delete(inter, locationRange) + + v.deleted = true + + return Void + }, + ) +} + +func (v *StorageCapabilityControllerValue) newTargetFunction( + inter *Interpreter, +) FunctionValue { + return v.newHostFunctionValue( + inter, sema.StorageCapabilityControllerTypeTargetFunctionType, - panicHostFunction, + func(invocation Invocation) Value { + return v.TargetPath + }, ) - v.RetargetFunction = NewHostFunctionValue( - gauge, +} + +func (v *StorageCapabilityControllerValue) newRetargetFunction( + inter *Interpreter, +) FunctionValue { + return v.newHostFunctionValue( + inter, sema.StorageCapabilityControllerTypeRetargetFunctionType, - panicHostFunction, - ) - v.DeleteFunction = NewHostFunctionValue( - gauge, - sema.StorageCapabilityControllerTypeDeleteFunctionType, - panicHostFunction, + func(invocation Invocation) Value { + inter := invocation.Interpreter + locationRange := invocation.LocationRange + + // Get path argument + + newTargetPathValue, ok := invocation.Arguments[0].(PathValue) + if !ok || newTargetPathValue.Domain != common.PathDomainStorage { + panic(errors.NewUnreachableError()) + } + + v.SetTarget(inter, locationRange, newTargetPathValue) + v.TargetPath = newTargetPathValue + + return Void + }, ) } func (v *StorageCapabilityControllerValue) newSetTagFunction( inter *Interpreter, -) *HostFunctionValue { - return NewHostFunctionValue( +) FunctionValue { + return v.newHostFunctionValue( inter, sema.StorageCapabilityControllerTypeSetTagFunctionType, func(invocation Invocation) Value { + inter := invocation.Interpreter + newTagValue, ok := invocation.Arguments[0].(*StringValue) if !ok { panic(errors.NewUnreachableError()) } - v.tag = newTagValue - v.SetTag(newTagValue) + v.SetTag(inter, newTagValue) return Void }, diff --git a/runtime/sema/account.gen.go b/runtime/sema/account.gen.go index 8b69d15bbb..6908cf6063 100644 --- a/runtime/sema/account.gen.go +++ b/runtime/sema/account.gen.go @@ -2099,57 +2099,30 @@ var CapabilitiesMappingType = &EntitlementMapType{ func init() { BuiltinEntitlementMappings[AccountMappingType.Identifier] = AccountMappingType - addToBaseActivation(AccountMappingType) BuiltinEntitlementMappings[CapabilitiesMappingType.Identifier] = CapabilitiesMappingType - addToBaseActivation(CapabilitiesMappingType) BuiltinEntitlements[StorageType.Identifier] = StorageType - addToBaseActivation(StorageType) BuiltinEntitlements[SaveValueType.Identifier] = SaveValueType - addToBaseActivation(SaveValueType) BuiltinEntitlements[LoadValueType.Identifier] = LoadValueType - addToBaseActivation(LoadValueType) BuiltinEntitlements[CopyValueType.Identifier] = CopyValueType - addToBaseActivation(CopyValueType) BuiltinEntitlements[BorrowValueType.Identifier] = BorrowValueType - addToBaseActivation(BorrowValueType) BuiltinEntitlements[ContractsType.Identifier] = ContractsType - addToBaseActivation(ContractsType) BuiltinEntitlements[AddContractType.Identifier] = AddContractType - addToBaseActivation(AddContractType) BuiltinEntitlements[UpdateContractType.Identifier] = UpdateContractType - addToBaseActivation(UpdateContractType) BuiltinEntitlements[RemoveContractType.Identifier] = RemoveContractType - addToBaseActivation(RemoveContractType) BuiltinEntitlements[KeysType.Identifier] = KeysType - addToBaseActivation(KeysType) BuiltinEntitlements[AddKeyType.Identifier] = AddKeyType - addToBaseActivation(AddKeyType) BuiltinEntitlements[RevokeKeyType.Identifier] = RevokeKeyType - addToBaseActivation(RevokeKeyType) BuiltinEntitlements[InboxType.Identifier] = InboxType - addToBaseActivation(InboxType) BuiltinEntitlements[PublishInboxCapabilityType.Identifier] = PublishInboxCapabilityType - addToBaseActivation(PublishInboxCapabilityType) BuiltinEntitlements[UnpublishInboxCapabilityType.Identifier] = UnpublishInboxCapabilityType - addToBaseActivation(UnpublishInboxCapabilityType) BuiltinEntitlements[ClaimInboxCapabilityType.Identifier] = ClaimInboxCapabilityType - addToBaseActivation(ClaimInboxCapabilityType) BuiltinEntitlements[CapabilitiesType.Identifier] = CapabilitiesType - addToBaseActivation(CapabilitiesType) BuiltinEntitlements[StorageCapabilitiesType.Identifier] = StorageCapabilitiesType - addToBaseActivation(StorageCapabilitiesType) BuiltinEntitlements[AccountCapabilitiesType.Identifier] = AccountCapabilitiesType - addToBaseActivation(AccountCapabilitiesType) BuiltinEntitlements[PublishCapabilityType.Identifier] = PublishCapabilityType - addToBaseActivation(PublishCapabilityType) BuiltinEntitlements[UnpublishCapabilityType.Identifier] = UnpublishCapabilityType - addToBaseActivation(UnpublishCapabilityType) BuiltinEntitlements[GetStorageCapabilityControllerType.Identifier] = GetStorageCapabilityControllerType - addToBaseActivation(GetStorageCapabilityControllerType) BuiltinEntitlements[IssueStorageCapabilityControllerType.Identifier] = IssueStorageCapabilityControllerType - addToBaseActivation(IssueStorageCapabilityControllerType) BuiltinEntitlements[GetAccountCapabilityControllerType.Identifier] = GetAccountCapabilityControllerType - addToBaseActivation(GetAccountCapabilityControllerType) BuiltinEntitlements[IssueAccountCapabilityControllerType.Identifier] = IssueAccountCapabilityControllerType - addToBaseActivation(IssueAccountCapabilityControllerType) } diff --git a/runtime/sema/account.go b/runtime/sema/account.go index ad7d988c1a..9d7a371fa0 100644 --- a/runtime/sema/account.go +++ b/runtime/sema/account.go @@ -56,4 +56,31 @@ var FullyEntitledAccountReferenceTypeAnnotation = NewTypeAnnotation(FullyEntitle func init() { Account_ContractsTypeAddFunctionType.Arity = &Arity{Min: 2} + addToBaseActivation(AccountMappingType) + addToBaseActivation(CapabilitiesMappingType) + addToBaseActivation(StorageType) + addToBaseActivation(SaveValueType) + addToBaseActivation(LoadValueType) + addToBaseActivation(CopyValueType) + addToBaseActivation(BorrowValueType) + addToBaseActivation(ContractsType) + addToBaseActivation(AddContractType) + addToBaseActivation(UpdateContractType) + addToBaseActivation(RemoveContractType) + addToBaseActivation(KeysType) + addToBaseActivation(AddKeyType) + addToBaseActivation(RevokeKeyType) + addToBaseActivation(InboxType) + addToBaseActivation(PublishInboxCapabilityType) + addToBaseActivation(UnpublishInboxCapabilityType) + addToBaseActivation(ClaimInboxCapabilityType) + addToBaseActivation(CapabilitiesType) + addToBaseActivation(StorageCapabilitiesType) + addToBaseActivation(AccountCapabilitiesType) + addToBaseActivation(PublishCapabilityType) + addToBaseActivation(UnpublishCapabilityType) + addToBaseActivation(GetStorageCapabilityControllerType) + addToBaseActivation(IssueStorageCapabilityControllerType) + addToBaseActivation(GetAccountCapabilityControllerType) + addToBaseActivation(IssueAccountCapabilityControllerType) } diff --git a/runtime/sema/account_capability_controller.gen.go b/runtime/sema/account_capability_controller.gen.go index c91e435e17..02d09d0769 100644 --- a/runtime/sema/account_capability_controller.gen.go +++ b/runtime/sema/account_capability_controller.gen.go @@ -102,7 +102,7 @@ var AccountCapabilityControllerType = &SimpleType{ Name: AccountCapabilityControllerTypeName, QualifiedName: AccountCapabilityControllerTypeName, TypeID: AccountCapabilityControllerTypeName, - tag: AccountCapabilityControllerTypeTag, + TypeTag: AccountCapabilityControllerTypeTag, IsResource: false, Storable: false, Equatable: false, diff --git a/runtime/sema/any_type.go b/runtime/sema/any_type.go index f5e0d97f41..7feaaf28dc 100644 --- a/runtime/sema/any_type.go +++ b/runtime/sema/any_type.go @@ -24,7 +24,7 @@ var AnyType = &SimpleType{ Name: "Any", QualifiedName: "Any", TypeID: "Any", - tag: AnyTypeTag, + TypeTag: AnyTypeTag, IsResource: false, // `Any` is never a valid type in user programs Storable: true, diff --git a/runtime/sema/anyattachment_types.go b/runtime/sema/anyattachment_types.go index c22f19c583..ef154c4926 100644 --- a/runtime/sema/anyattachment_types.go +++ b/runtime/sema/anyattachment_types.go @@ -25,7 +25,7 @@ var AnyResourceAttachmentType = &SimpleType{ Name: AnyResourceAttachmentTypeName, QualifiedName: AnyResourceAttachmentTypeName, TypeID: AnyResourceAttachmentTypeName, - tag: AnyResourceAttachmentTypeTag, + TypeTag: AnyResourceAttachmentTypeTag, IsResource: true, // The actual storability of a value is checked at run-time Storable: true, @@ -43,7 +43,7 @@ var AnyStructAttachmentType = &SimpleType{ Name: AnyStructAttachmentTypeName, QualifiedName: AnyStructAttachmentTypeName, TypeID: AnyStructAttachmentTypeName, - tag: AnyStructAttachmentTypeTag, + TypeTag: AnyStructAttachmentTypeTag, IsResource: false, // The actual storability of a value is checked at run-time Storable: true, diff --git a/runtime/sema/anyresource_type.go b/runtime/sema/anyresource_type.go index b19d72040f..6b20d9563a 100644 --- a/runtime/sema/anyresource_type.go +++ b/runtime/sema/anyresource_type.go @@ -23,7 +23,7 @@ var AnyResourceType = &SimpleType{ Name: "AnyResource", QualifiedName: "AnyResource", TypeID: "AnyResource", - tag: AnyResourceTypeTag, + TypeTag: AnyResourceTypeTag, IsResource: true, // The actual storability of a value is checked at run-time Storable: true, diff --git a/runtime/sema/anystruct_type.go b/runtime/sema/anystruct_type.go index edbc5e8220..a4739610a3 100644 --- a/runtime/sema/anystruct_type.go +++ b/runtime/sema/anystruct_type.go @@ -23,7 +23,7 @@ var AnyStructType = &SimpleType{ Name: "AnyStruct", QualifiedName: "AnyStruct", TypeID: "AnyStruct", - tag: AnyStructTypeTag, + TypeTag: AnyStructTypeTag, IsResource: false, // The actual storability of a value is checked at run-time Storable: true, diff --git a/runtime/sema/block.gen.go b/runtime/sema/block.gen.go index 058282a4ff..7c490c3a0c 100644 --- a/runtime/sema/block.gen.go +++ b/runtime/sema/block.gen.go @@ -69,7 +69,7 @@ var BlockType = &SimpleType{ Name: BlockTypeName, QualifiedName: BlockTypeName, TypeID: BlockTypeName, - tag: BlockTypeTag, + TypeTag: BlockTypeTag, IsResource: false, Storable: false, Equatable: false, diff --git a/runtime/sema/bool_type.go b/runtime/sema/bool_type.go index c83a2eafc1..1870777d78 100644 --- a/runtime/sema/bool_type.go +++ b/runtime/sema/bool_type.go @@ -23,7 +23,7 @@ var BoolType = &SimpleType{ Name: "Bool", QualifiedName: "Bool", TypeID: "Bool", - tag: BoolTypeTag, + TypeTag: BoolTypeTag, IsResource: false, Storable: true, Equatable: true, diff --git a/runtime/sema/character.gen.go b/runtime/sema/character.gen.go index 36d89e50c4..69909c376f 100644 --- a/runtime/sema/character.gen.go +++ b/runtime/sema/character.gen.go @@ -50,7 +50,7 @@ var CharacterType = &SimpleType{ Name: CharacterTypeName, QualifiedName: CharacterTypeName, TypeID: CharacterTypeName, - tag: CharacterTypeTag, + TypeTag: CharacterTypeTag, IsResource: false, Storable: true, Equatable: true, diff --git a/runtime/sema/check_function.go b/runtime/sema/check_function.go index 26c4ec7228..db4204b7fb 100644 --- a/runtime/sema/check_function.go +++ b/runtime/sema/check_function.go @@ -79,6 +79,21 @@ func (checker *Checker) visitFunctionDeclaration( declaration.Identifier, ) + functionBlock := declaration.FunctionBlock + + if declaration.IsNative() { + if !functionBlock.IsEmpty() { + checker.report(&NativeFunctionWithImplementationError{ + Range: ast.NewRangeFromPositioned( + checker.memoryGauge, + functionBlock, + ), + }) + } + + functionBlock = nil + } + // global functions were previously declared, see `declareFunctionDeclaration` functionType := checker.Elaboration.FunctionDeclarationFunctionType(declaration) @@ -108,7 +123,7 @@ func (checker *Checker) visitFunctionDeclaration( declaration.ReturnTypeAnnotation, access, functionType, - declaration.FunctionBlock, + functionBlock, options.mustExit, nil, options.checkResourceLoss, @@ -344,7 +359,10 @@ func (checker *Checker) visitWithPostConditions(postConditions *ast.Conditions, checker.Elaboration.SetPostConditionsRewrite(postConditions, rewriteResult) - checker.visitStatements(rewriteResult.BeforeStatements) + // all condition blocks are `view` + checker.InNewPurityScope(true, func() { + checker.visitStatements(rewriteResult.BeforeStatements) + }) } body() diff --git a/runtime/sema/check_interface_declaration.go b/runtime/sema/check_interface_declaration.go index 51d798896b..45934ed77a 100644 --- a/runtime/sema/check_interface_declaration.go +++ b/runtime/sema/check_interface_declaration.go @@ -529,6 +529,7 @@ func (checker *Checker) declareEntitlementMappingType(declaration *ast.Entitleme checker.report(&InvalidNonEntitlementTypeInMapError{ Pos: association.Input.Identifier.Pos, }) + continue } output := checker.convertNominalType(association.Output) @@ -538,6 +539,7 @@ func (checker *Checker) declareEntitlementMappingType(declaration *ast.Entitleme checker.report(&InvalidNonEntitlementTypeInMapError{ Pos: association.Output.Identifier.Pos, }) + continue } entitlementRelations = append( diff --git a/runtime/sema/check_member_expression.go b/runtime/sema/check_member_expression.go index 4d717c09ac..4d1d044a0d 100644 --- a/runtime/sema/check_member_expression.go +++ b/runtime/sema/check_member_expression.go @@ -419,6 +419,8 @@ func (checker *Checker) isReadableMember(accessedType Type, member *Member, resu } case EntitlementSetAccess: switch ty := accessedType.(type) { + case *OptionalType: + return checker.isReadableMember(ty.Type, member, resultingType, accessRange) case *ReferenceType: // when accessing a member on a reference, the read is allowed if // the member's access permits the reference's authorization @@ -453,6 +455,28 @@ func (checker *Checker) mapAccess( // pretend that the access succeeds to prevent a redundant access error report return true, UnauthorizedAccess } + // when we are in an assignment statement, + // we need full permissions to the map regardless of the input authorization of the reference + // Consider: + // + // entitlement X + // entitlement Y + // entitlement mapping M { + // X -> Insert + // Y -> Remove + // } + // struct S { + // access(M) var member: auth(M) &[T]? + // ... + // } + // + // If we were able to assign a `auth(Insert) &[T]` value to `ref.member` when `ref` has type `auth(X) &S` + // we could use this to then extract a `auth(Insert, Remove) &[T]` reference to that array by accessing `member` + // on an owned copy of `S`. As such, when in an assignment, we return the full codomain here as the "granted authorization" + // of the access expression, since the checker will later enforce that the incoming reference value is a subtype of that full codomain. + if checker.inAssignment { + return true, mappedAccess.Codomain() + } return true, grantedAccess case *OptionalType: diff --git a/runtime/sema/deployedcontract.gen.go b/runtime/sema/deployedcontract.gen.go index 1e502abccd..864c5dd718 100644 --- a/runtime/sema/deployedcontract.gen.go +++ b/runtime/sema/deployedcontract.gen.go @@ -78,7 +78,7 @@ var DeployedContractType = &SimpleType{ Name: DeployedContractTypeName, QualifiedName: DeployedContractTypeName, TypeID: DeployedContractTypeName, - tag: DeployedContractTypeTag, + TypeTag: DeployedContractTypeTag, IsResource: false, Storable: false, Equatable: false, diff --git a/runtime/sema/entitlements.gen.go b/runtime/sema/entitlements.gen.go index 559ebf6937..5ae0d1b995 100644 --- a/runtime/sema/entitlements.gen.go +++ b/runtime/sema/entitlements.gen.go @@ -33,9 +33,6 @@ var RemoveType = &EntitlementType{ func init() { BuiltinEntitlements[MutateType.Identifier] = MutateType - addToBaseActivation(MutateType) BuiltinEntitlements[InsertType.Identifier] = InsertType - addToBaseActivation(InsertType) BuiltinEntitlements[RemoveType.Identifier] = RemoveType - addToBaseActivation(RemoveType) } diff --git a/runtime/sema/entitlements.go b/runtime/sema/entitlements.go index d2cbeebd04..3870c6e5cf 100644 --- a/runtime/sema/entitlements.go +++ b/runtime/sema/entitlements.go @@ -19,3 +19,9 @@ package sema //go:generate go run ./gen entitlements.cdc entitlements.gen.go + +func init() { + addToBaseActivation(MutateType) + addToBaseActivation(InsertType) + addToBaseActivation(RemoveType) +} diff --git a/runtime/sema/errors.go b/runtime/sema/errors.go index d15dce1be6..5d31b1d552 100644 --- a/runtime/sema/errors.go +++ b/runtime/sema/errors.go @@ -862,6 +862,23 @@ func (e *InvalidNativeModifierError) Error() string { return "invalid native modifier for declaration" } +// NativeFunctionWithImplementationError + +type NativeFunctionWithImplementationError struct { + ast.Range +} + +var _ SemanticError = &NativeFunctionWithImplementationError{} +var _ errors.UserError = &NativeFunctionWithImplementationError{} + +func (*NativeFunctionWithImplementationError) isSemanticError() {} + +func (*NativeFunctionWithImplementationError) IsUserError() {} + +func (e *NativeFunctionWithImplementationError) Error() string { + return "native function must not have an implementation" +} + // InvalidNameError type InvalidNameError struct { diff --git a/runtime/sema/gen/golden_test.go b/runtime/sema/gen/golden_test.go new file mode 100644 index 0000000000..6eccdc779d --- /dev/null +++ b/runtime/sema/gen/golden_test.go @@ -0,0 +1,95 @@ +/* + * Cadence - The resource-oriented smart contract programming language + * + * Copyright Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package main + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onflow/cadence/runtime/common" + "github.com/onflow/cadence/runtime/sema" + _ "github.com/onflow/cadence/runtime/sema/gen/testdata/comparable" + _ "github.com/onflow/cadence/runtime/sema/gen/testdata/composite_type_pragma" + "github.com/onflow/cadence/runtime/sema/gen/testdata/constructor" + "github.com/onflow/cadence/runtime/sema/gen/testdata/contract" + _ "github.com/onflow/cadence/runtime/sema/gen/testdata/contract" + _ "github.com/onflow/cadence/runtime/sema/gen/testdata/docstrings" + _ "github.com/onflow/cadence/runtime/sema/gen/testdata/entitlement" + _ "github.com/onflow/cadence/runtime/sema/gen/testdata/equatable" + _ "github.com/onflow/cadence/runtime/sema/gen/testdata/exportable" + _ "github.com/onflow/cadence/runtime/sema/gen/testdata/fields" + _ "github.com/onflow/cadence/runtime/sema/gen/testdata/functions" + _ "github.com/onflow/cadence/runtime/sema/gen/testdata/importable" + _ "github.com/onflow/cadence/runtime/sema/gen/testdata/member_accessible" + _ "github.com/onflow/cadence/runtime/sema/gen/testdata/nested" + _ "github.com/onflow/cadence/runtime/sema/gen/testdata/simple_resource" + _ "github.com/onflow/cadence/runtime/sema/gen/testdata/simple_struct" + _ "github.com/onflow/cadence/runtime/sema/gen/testdata/storable" + "github.com/onflow/cadence/runtime/stdlib" + "github.com/onflow/cadence/runtime/tests/checker" +) + +func TestConstructor(t *testing.T) { + + t.Parallel() + + baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) + baseValueActivation.DeclareValue(stdlib.StandardLibraryValue{ + Name: constructor.FooType.Identifier, + Type: constructor.FooTypeConstructorType, + Kind: common.DeclarationKindFunction, + }) + + _, err := checker.ParseAndCheckWithOptions(t, + ` + let x = Foo(bar: 1) + `, + checker.ParseAndCheckOptions{ + Config: &sema.Config{ + BaseValueActivation: baseValueActivation, + }, + }, + ) + require.NoError(t, err) +} + +func TestContract(t *testing.T) { + + t.Parallel() + + baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) + baseValueActivation.DeclareValue(stdlib.StandardLibraryValue{ + Name: contract.TestType.Identifier, + Type: contract.TestType, + Kind: common.DeclarationKindContract, + }) + + _, err := checker.ParseAndCheckWithOptions(t, + ` + let x = Test.Foo(bar: 1) + `, + checker.ParseAndCheckOptions{ + Config: &sema.Config{ + BaseValueActivation: baseValueActivation, + }, + }, + ) + require.NoError(t, err) +} diff --git a/runtime/sema/gen/main.go b/runtime/sema/gen/main.go index 3fd35f3e5b..b7778b0a97 100644 --- a/runtime/sema/gen/main.go +++ b/runtime/sema/gen/main.go @@ -38,6 +38,7 @@ import ( "github.com/onflow/cadence/runtime/errors" "github.com/onflow/cadence/runtime/parser" "github.com/onflow/cadence/runtime/pretty" + "github.com/onflow/cadence/runtime/sema" ) const semaPath = "github.com/onflow/cadence/runtime/sema" @@ -161,6 +162,7 @@ type typeDecl struct { memberAccessible bool memberDeclarations []ast.Declaration nestedTypes []*typeDecl + hasConstructor bool } type generator struct { @@ -289,6 +291,7 @@ func (g *generator) addFunctionTypeDeclaration( decl.ParameterList, decl.TypeParameterList, typeParams, + false, ), ), ) @@ -323,8 +326,106 @@ func (g *generator) declarationDocString(decl ast.Declaration) dst.Expr { return renderDocString(docString) } -func (*generator) VisitSpecialFunctionDeclaration(_ *ast.SpecialFunctionDeclaration) struct{} { - panic("special function declarations are not supported") +func (g *generator) VisitSpecialFunctionDeclaration(decl *ast.SpecialFunctionDeclaration) (_ struct{}) { + if decl.Kind != common.DeclarationKindInitializer { + panic(fmt.Errorf( + "%s special function declarations are not supported", + decl.Kind.Name(), + )) + } + + typeDecl := g.currentTypeDecl() + + fullTypeName := typeDecl.fullTypeName + + if typeDecl.hasConstructor { + panic(fmt.Errorf("invalid second initializer for type %s", fullTypeName)) + } + typeDecl.hasConstructor = true + + isResource := typeDecl.compositeKind == common.CompositeKindResource + + typeNames := make([]string, 0, len(g.typeStack)) + for i := 0; i < len(g.typeStack); i++ { + typeNames = append(typeNames, g.typeStack[i].typeName) + } + + g.addConstructorTypeDeclaration(decl, fullTypeName, typeNames, isResource) + + g.addConstructorDocStringDeclaration(decl, fullTypeName) + + return +} + +func (g *generator) addConstructorTypeDeclaration( + initDecl *ast.SpecialFunctionDeclaration, + fullTypeName string, + typeNames []string, + isResource bool, +) { + decl := initDecl.FunctionDeclaration + + parameters := decl.ParameterList.Parameters + + parameterTypeAnnotations := make([]*ast.TypeAnnotation, 0, len(parameters)) + for _, parameter := range parameters { + parameterTypeAnnotations = append( + parameterTypeAnnotations, + parameter.TypeAnnotation, + ) + } + + nestedIdentifiers := make([]ast.Identifier, 0, len(typeNames)-1) + for i := 1; i < len(typeNames); i++ { + typeName := typeNames[i] + nestedIdentifiers = append( + nestedIdentifiers, + ast.Identifier{ + Identifier: typeName, + }, + ) + } + + returnType := &ast.NominalType{ + NestedIdentifiers: nestedIdentifiers, + Identifier: ast.Identifier{ + Identifier: typeNames[0], + }, + } + + g.addDecls( + goVarDecl( + constructorTypeVarName(fullTypeName), + functionTypeExpr( + &ast.FunctionType{ + PurityAnnotation: decl.Purity, + ReturnTypeAnnotation: &ast.TypeAnnotation{ + Type: returnType, + IsResource: isResource, + }, + ParameterTypeAnnotations: parameterTypeAnnotations, + }, + decl.ParameterList, + nil, + nil, + true, + ), + ), + ) +} + +func (g *generator) addConstructorDocStringDeclaration( + decl *ast.SpecialFunctionDeclaration, + fullTypeName string, +) { + docString := g.declarationDocString(decl) + + g.addDecls( + goConstDecl( + constructorDocStringVarName(fullTypeName), + docString, + ), + ) } func (g *generator) VisitCompositeDeclaration(decl *ast.CompositeDeclaration) (_ struct{}) { @@ -471,11 +572,13 @@ func (g *generator) VisitCompositeDeclaration(decl *ast.CompositeDeclaration) (_ typeVarDecl = compositeTypeExpr(typeDecl) } - tyVarName := typeVarName(typeDecl.fullTypeName) + fullTypeName := typeDecl.fullTypeName + + tyVarName := typeVarName(fullTypeName) g.addDecls( goConstDecl( - typeNameVarName(typeDecl.fullTypeName), + typeNameVarName(fullTypeName), goStringLit(typeName), ), goVarDecl( @@ -496,7 +599,7 @@ func (g *generator) VisitCompositeDeclaration(decl *ast.CompositeDeclaration) (_ // } // } - memberResolversFunc := simpleTypeMemberResolversFunc(typeDecl.fullTypeName, memberDeclarations) + memberResolversFunc := simpleTypeMemberResolversFunc(fullTypeName, memberDeclarations) g.addDecls( &dst.FuncDecl{ @@ -527,65 +630,93 @@ func (g *generator) VisitCompositeDeclaration(decl *ast.CompositeDeclaration) (_ // members := []*Member{...} // t.Members = MembersAsMap(members) // t.Fields = MembersFieldNames(members) + // t.ConstructorParameters = ... // } - members := membersExpr(typeDecl.fullTypeName, tyVarName, memberDeclarations) + members := membersExpr( + fullTypeName, + tyVarName, + memberDeclarations, + ) const membersVariableIdentifier = "members" + stmts := []dst.Stmt{ + &dst.DeclStmt{ + Decl: goVarDecl( + membersVariableIdentifier, + members, + ), + }, + &dst.AssignStmt{ + Lhs: []dst.Expr{ + &dst.SelectorExpr{ + X: dst.NewIdent(tyVarName), + Sel: dst.NewIdent("Members"), + }, + }, + Tok: token.ASSIGN, + Rhs: []dst.Expr{ + &dst.CallExpr{ + Fun: &dst.Ident{ + Name: "MembersAsMap", + Path: semaPath, + }, + Args: []dst.Expr{ + dst.NewIdent(membersVariableIdentifier), + }, + }, + }, + }, + &dst.AssignStmt{ + Lhs: []dst.Expr{ + &dst.SelectorExpr{ + X: dst.NewIdent(tyVarName), + Sel: dst.NewIdent("Fields"), + }, + }, + Tok: token.ASSIGN, + Rhs: []dst.Expr{ + &dst.CallExpr{ + Fun: &dst.Ident{ + Name: "MembersFieldNames", + Path: semaPath, + }, + Args: []dst.Expr{ + dst.NewIdent(membersVariableIdentifier), + }, + }, + }, + }, + } + + if typeDecl.hasConstructor { + stmts = append( + stmts, + &dst.AssignStmt{ + Lhs: []dst.Expr{ + &dst.SelectorExpr{ + X: dst.NewIdent(tyVarName), + Sel: dst.NewIdent("ConstructorParameters"), + }, + }, + Tok: token.ASSIGN, + Rhs: []dst.Expr{ + &dst.SelectorExpr{ + X: dst.NewIdent(constructorTypeVarName(fullTypeName)), + Sel: dst.NewIdent("Parameters"), + }, + }, + }, + ) + } + g.addDecls( &dst.FuncDecl{ Name: dst.NewIdent("init"), Type: &dst.FuncType{}, Body: &dst.BlockStmt{ - List: []dst.Stmt{ - &dst.DeclStmt{ - Decl: goVarDecl( - membersVariableIdentifier, - members, - ), - }, - &dst.AssignStmt{ - Lhs: []dst.Expr{ - &dst.SelectorExpr{ - X: dst.NewIdent(tyVarName), - Sel: dst.NewIdent("Members"), - }, - }, - Tok: token.ASSIGN, - Rhs: []dst.Expr{ - &dst.CallExpr{ - Fun: &dst.Ident{ - Name: "MembersAsMap", - Path: semaPath, - }, - Args: []dst.Expr{ - dst.NewIdent(membersVariableIdentifier), - }, - }, - }, - }, - &dst.AssignStmt{ - Lhs: []dst.Expr{ - &dst.SelectorExpr{ - X: dst.NewIdent(tyVarName), - Sel: dst.NewIdent("Fields"), - }, - }, - Tok: token.ASSIGN, - Rhs: []dst.Expr{ - &dst.CallExpr{ - Fun: &dst.Ident{ - Name: "MembersFieldNames", - Path: semaPath, - }, - Args: []dst.Expr{ - dst.NewIdent(membersVariableIdentifier), - }, - }, - }, - }, - }, + List: stmts, }, }, ) @@ -662,7 +793,11 @@ func (g *generator) VisitFieldDeclaration(decl *ast.FieldDeclaration) (_ struct{ } func (g *generator) currentFullTypeName() string { - return g.typeStack[len(g.typeStack)-1].fullTypeName + return g.currentTypeDecl().fullTypeName +} + +func (g *generator) currentTypeDecl() *typeDecl { + return g.typeStack[len(g.typeStack)-1] } func typeExpr(t ast.Type, typeParams map[string]string) dst.Expr { @@ -686,9 +821,14 @@ func typeExpr(t ast.Type, typeParams map[string]string) dst.Expr { } } + inSema := sema.BaseTypeActivation.Find(identifier) != nil + switch identifier { case "": identifier = "Void" + inSema = true + case "Any": + inSema = true case "Address": identifier = "TheAddress" case "Type": @@ -715,7 +855,11 @@ func typeExpr(t ast.Type, typeParams map[string]string) dst.Expr { identifier = fullIdentifier.String() } - return typeVarIdent(identifier) + ident := typeVarIdent(identifier) + if inSema { + ident.Path = semaPath + } + return ident case *ast.OptionalType: innerType := typeExpr(t.Type, typeParams) @@ -810,7 +954,13 @@ func typeExpr(t ast.Type, typeParams map[string]string) dst.Expr { } case *ast.FunctionType: - return functionTypeExpr(t, nil, nil, typeParams) + return functionTypeExpr( + t, + nil, + nil, + typeParams, + false, + ) case *ast.InstantiationType: typeArguments := t.TypeArguments @@ -888,6 +1038,7 @@ func functionTypeExpr( parameters *ast.ParameterList, typeParameterList *ast.TypeParameterList, typeParams map[string]string, + isConstructor bool, ) dst.Expr { // Function purity @@ -1020,7 +1171,14 @@ func functionTypeExpr( if t.ReturnTypeAnnotation != nil { returnTypeExpr = typeExpr(t.ReturnTypeAnnotation.Type, typeParams) } else { - returnTypeExpr = typeVarIdent("Void") + returnTypeExpr = typeExpr( + &ast.NominalType{ + Identifier: ast.Identifier{ + Identifier: "Void", + }, + }, + nil, + ) } returnTypeExpr.Decorations().Before = dst.NewLine @@ -1040,6 +1198,16 @@ func functionTypeExpr( ) } + if isConstructor { + compositeElements = append( + compositeElements, + goKeyValue( + "IsConstructor", + goBoolLit(true), + ), + ) + } + if typeParametersExpr != nil { compositeElements = append( compositeElements, @@ -1106,11 +1274,7 @@ func (*generator) VisitImportDeclaration(_ *ast.ImportDeclaration) struct{} { const typeNameSeparator = '_' -func (g *generator) newFullTypeName(typeName string) string { - if len(g.typeStack) == 0 { - return typeName - } - parentFullTypeName := g.typeStack[len(g.typeStack)-1].fullTypeName +func joinTypeName(parentFullTypeName string, typeName string) string { return fmt.Sprintf( "%s%c%s", escapeTypeName(parentFullTypeName), @@ -1119,6 +1283,14 @@ func (g *generator) newFullTypeName(typeName string) string { ) } +func (g *generator) newFullTypeName(typeName string) string { + if len(g.typeStack) == 0 { + return typeName + } + parentFullTypeName := g.typeStack[len(g.typeStack)-1].fullTypeName + return joinTypeName(parentFullTypeName, typeName) +} + func escapeTypeName(typeName string) string { return strings.ReplaceAll(typeName, string(typeNameSeparator), "__") } @@ -1157,12 +1329,10 @@ func (g *generator) generateTypeInit(program *ast.Program) { // // func init() { // BuiltinEntitlements[FooEntitlement.Identifier] = FooEntitlement - // addToBaseActivation(FooEntitlement) // // ... // // BuiltinEntitlements[BarEntitlementMapping.Identifier] = BarEntitlementMapping - // addToBaseActivation(BarEntitlementMapping) // // ... // } @@ -1205,7 +1375,10 @@ func entitlementMapInitStatements(declaration *ast.EntitlementMappingDeclaration mapUpdateStmt := &dst.AssignStmt{ Lhs: []dst.Expr{ &dst.IndexExpr{ - X: dst.NewIdent(mapName), + X: &dst.Ident{ + Name: mapName, + Path: semaPath, + }, Index: &dst.SelectorExpr{ X: dst.NewIdent(varName), Sel: dst.NewIdent("Identifier"), @@ -1218,18 +1391,8 @@ func entitlementMapInitStatements(declaration *ast.EntitlementMappingDeclaration }, } - typeRegisterStmt := &dst.ExprStmt{ - X: &dst.CallExpr{ - Fun: dst.NewIdent("addToBaseActivation"), - Args: []dst.Expr{ - dst.NewIdent(varName), - }, - }, - } - return []dst.Stmt{ mapUpdateStmt, - typeRegisterStmt, } } @@ -1240,7 +1403,10 @@ func entitlementInitStatements(declaration *ast.EntitlementDeclaration) []dst.St mapUpdateStmt := &dst.AssignStmt{ Lhs: []dst.Expr{ &dst.IndexExpr{ - X: dst.NewIdent(mapName), + X: &dst.Ident{ + Name: mapName, + Path: semaPath, + }, Index: &dst.SelectorExpr{ X: dst.NewIdent(varName), Sel: dst.NewIdent("Identifier"), @@ -1253,18 +1419,8 @@ func entitlementInitStatements(declaration *ast.EntitlementDeclaration) []dst.St }, } - typeRegisterStmt := &dst.ExprStmt{ - X: &dst.CallExpr{ - Fun: dst.NewIdent("addToBaseActivation"), - Args: []dst.Expr{ - dst.NewIdent(varName), - }, - }, - } - return []dst.Stmt{ mapUpdateStmt, - typeRegisterStmt, } } @@ -1345,24 +1501,24 @@ func compositeKindExpr(compositeKind common.CompositeKind) *dst.Ident { } } -func typeVarName(typeName string) string { - return fmt.Sprintf("%sType", typeName) +func typeVarName(fullTypeName string) string { + return fmt.Sprintf("%sType", fullTypeName) } -func typeVarIdent(typeName string) *dst.Ident { - return dst.NewIdent(typeVarName(typeName)) +func typeVarIdent(fullTypeName string) *dst.Ident { + return dst.NewIdent(typeVarName(fullTypeName)) } -func typeNameVarName(typeName string) string { - return fmt.Sprintf("%sTypeName", typeName) +func typeNameVarName(fullTypeName string) string { + return fmt.Sprintf("%sTypeName", fullTypeName) } -func typeNameVarIdent(typeName string) *dst.Ident { - return dst.NewIdent(typeNameVarName(typeName)) +func typeNameVarIdent(fullTypeName string) *dst.Ident { + return dst.NewIdent(typeNameVarName(fullTypeName)) } -func typeTagVarIdent(typeName string) *dst.Ident { - return dst.NewIdent(fmt.Sprintf("%sTypeTag", typeName)) +func typeTagVarIdent(fullTypeName string) *dst.Ident { + return dst.NewIdent(fmt.Sprintf("%sTypeTag", fullTypeName)) } func memberVarName(fullTypeName, fieldName, kind, part string) string { @@ -1391,6 +1547,10 @@ func functionTypeVarName(fullTypeName, functionName string) string { return memberVarName(fullTypeName, functionName, "Function", "Type") } +func constructorTypeVarName(fullTypeName string) string { + return memberVarName(fullTypeName, "", "Constructor", "Type") +} + func functionTypeParameterVarName(fullTypeName, functionName, typeParameterName string) string { return memberVarName(fullTypeName, functionName, "Function", "TypeParameter"+typeParameterName) } @@ -1403,6 +1563,10 @@ func functionDocStringVarName(fullTypeName, functionName string) string { return memberVarName(fullTypeName, functionName, "Function", "DocString") } +func constructorDocStringVarName(fullTypeName string) string { + return memberVarName(fullTypeName, "", "Constructor", "DocString") +} + func simpleTypeLiteral(ty *typeDecl) dst.Expr { // &SimpleType{ @@ -1423,7 +1587,7 @@ func simpleTypeLiteral(ty *typeDecl) dst.Expr { goKeyValue("Name", typeNameVarIdent(ty.fullTypeName)), goKeyValue("QualifiedName", typeNameVarIdent(ty.fullTypeName)), goKeyValue("TypeID", typeNameVarIdent(ty.fullTypeName)), - goKeyValue("tag", typeTagVarIdent(ty.fullTypeName)), + goKeyValue("TypeTag", typeTagVarIdent(ty.fullTypeName)), goKeyValue("IsResource", goBoolLit(isResource)), goKeyValue("Storable", goBoolLit(ty.storable)), goKeyValue("Equatable", goBoolLit(ty.equatable)), @@ -1460,7 +1624,11 @@ func simpleTypeMemberResolversFunc(fullTypeName string, declarations []ast.Decla Path: semaPath, }, Args: []dst.Expr{ - membersExpr(fullTypeName, typeVarName, declarations), + membersExpr( + fullTypeName, + typeVarName, + declarations, + ), }, }, }, @@ -1522,11 +1690,34 @@ func membersExpr( memberName, ) + case common.DeclarationKindInitializer: + // Generated as a member of the container + continue + case common.DeclarationKindStructureInterface, common.DeclarationKindStructure, common.DeclarationKindResource, common.DeclarationKindResourceInterface: + initializers := declaration.DeclarationMembers().Initializers() + if len(initializers) > 0 { + initializer := initializers[0] + + typeName := declaration.DeclarationIdentifier().Identifier + + element := newDeclarationMember( + joinTypeName(fullTypeName, typeName), + typeVarName, + // type name is used instead + "", + initializer, + ) + element.Decorations().Before = dst.NewLine + element.Decorations().After = dst.NewLine + + elements = append(elements, element) + } + continue default: @@ -1536,7 +1727,12 @@ func membersExpr( )) } - element := newDeclarationMember(fullTypeName, typeVarName, memberVarName, declaration) + element := newDeclarationMember( + fullTypeName, + typeVarName, + memberVarName, + declaration, + ) element.Decorations().Before = dst.NewLine element.Decorations().After = dst.NewLine @@ -1658,11 +1854,17 @@ func newDeclarationMember( access := declaration.DeclarationAccess() if access == ast.AccessNotSpecified { - panic(fmt.Errorf( - "member with unspecified access: %s.%s", - fullTypeName, - declarationName, - )) + switch declaration.DeclarationKind() { + case common.DeclarationKindInitializer: + access = ast.AccessAll + + default: + panic(fmt.Errorf( + "member with unspecified access: %s.%s", + fullTypeName, + declarationName, + )) + } } if fieldDeclaration, ok := declaration.(*ast.FieldDeclaration); ok { @@ -1691,9 +1893,10 @@ func newDeclarationMember( declarationKind := declaration.DeclarationKind() - // Function + // Function or initializer - if declarationKind == common.DeclarationKindFunction { + switch declarationKind { + case common.DeclarationKindFunction: args := []dst.Expr{ dst.NewIdent(containerTypeVariableIdentifier), accessExpr(access), @@ -1714,8 +1917,32 @@ func newDeclarationMember( }, Args: args, } + + case common.DeclarationKindInitializer: + args := []dst.Expr{ + dst.NewIdent(containerTypeVariableIdentifier), + accessExpr(access), + typeNameVarIdent(fullTypeName), + dst.NewIdent(constructorTypeVarName(fullTypeName)), + dst.NewIdent(constructorDocStringVarName(fullTypeName)), + } + + for _, arg := range args { + arg.Decorations().Before = dst.NewLine + arg.Decorations().After = dst.NewLine + } + + return &dst.CallExpr{ + Fun: &dst.Ident{ + Name: "NewUnmeteredConstructorMember", + Path: semaPath, + }, + Args: args, + } } + // Unsupported + panic(fmt.Errorf( "%s members are not supported", declarationKind.Name(), diff --git a/runtime/sema/gen/main_test.go b/runtime/sema/gen/main_test.go index 1e8def123d..e1862abb96 100644 --- a/runtime/sema/gen/main_test.go +++ b/runtime/sema/gen/main_test.go @@ -38,21 +38,22 @@ func TestFiles(t *testing.T) { t.Parallel() - test := func(inputPath string) { - // The test name is the filename without the extension. - _, filename := filepath.Split(inputPath) - testname := filename[:len(filename)-len(filepath.Ext(inputPath))] + test := func(dirPath string) { + // The test name is the directory name + _, testName := filepath.Split(dirPath) - t.Run(testname, func(t *testing.T) { + t.Run(testName, func(t *testing.T) { t.Parallel() outFile, err := os.CreateTemp(t.TempDir(), "gen.*.go") require.NoError(t, err) defer outFile.Close() - gen(inputPath, outFile, "github.com/onflow/cadence/runtime/sema") + inputPath := filepath.Join(dirPath, "test.cdc") - goldenPath := filepath.Join(testDataDirectory, testname+".golden.go") + gen(inputPath, outFile, "github.com/onflow/cadence/runtime/sema/gen/"+dirPath) + + goldenPath := filepath.Join(dirPath, "test.golden.go") want, err := os.ReadFile(goldenPath) require.NoError(t, err) @@ -66,7 +67,7 @@ func TestFiles(t *testing.T) { }) } - paths, err := filepath.Glob(filepath.Join(testDataDirectory, "*.cdc")) + paths, err := filepath.Glob(filepath.Join(testDataDirectory, "*")) require.NoError(t, err) for _, path := range paths { diff --git a/runtime/sema/gen/testdata/comparable/helper.go b/runtime/sema/gen/testdata/comparable/helper.go new file mode 100644 index 0000000000..efc83f3b98 --- /dev/null +++ b/runtime/sema/gen/testdata/comparable/helper.go @@ -0,0 +1,23 @@ +/* + * Cadence - The resource-oriented smart contract programming language + * + * Copyright Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package comparable + +import "github.com/onflow/cadence/runtime/sema" + +var TestTypeTag sema.TypeTag diff --git a/runtime/sema/gen/testdata/comparable.cdc b/runtime/sema/gen/testdata/comparable/test.cdc similarity index 100% rename from runtime/sema/gen/testdata/comparable.cdc rename to runtime/sema/gen/testdata/comparable/test.cdc diff --git a/runtime/sema/gen/testdata/comparable.golden.go b/runtime/sema/gen/testdata/comparable/test.golden.go similarity index 82% rename from runtime/sema/gen/testdata/comparable.golden.go rename to runtime/sema/gen/testdata/comparable/test.golden.go index 610a531517..c088f5d175 100644 --- a/runtime/sema/gen/testdata/comparable.golden.go +++ b/runtime/sema/gen/testdata/comparable/test.golden.go @@ -1,4 +1,4 @@ -// Code generated from testdata/comparable.cdc. DO NOT EDIT. +// Code generated from testdata/comparable/test.cdc. DO NOT EDIT. /* * Cadence - The resource-oriented smart contract programming language * @@ -17,15 +17,17 @@ * limitations under the License. */ -package sema +package comparable + +import "github.com/onflow/cadence/runtime/sema" const TestTypeName = "Test" -var TestType = &SimpleType{ +var TestType = &sema.SimpleType{ Name: TestTypeName, QualifiedName: TestTypeName, TypeID: TestTypeName, - tag: TestTypeTag, + TypeTag: TestTypeTag, IsResource: false, Storable: false, Equatable: false, diff --git a/runtime/sema/gen/testdata/composite-type-pragma.cdc b/runtime/sema/gen/testdata/composite_type_pragma/test.cdc similarity index 100% rename from runtime/sema/gen/testdata/composite-type-pragma.cdc rename to runtime/sema/gen/testdata/composite_type_pragma/test.cdc diff --git a/runtime/sema/gen/testdata/composite-type-pragma.golden.go b/runtime/sema/gen/testdata/composite_type_pragma/test.golden.go similarity index 75% rename from runtime/sema/gen/testdata/composite-type-pragma.golden.go rename to runtime/sema/gen/testdata/composite_type_pragma/test.golden.go index f975ff112f..0ce3c47a03 100644 --- a/runtime/sema/gen/testdata/composite-type-pragma.golden.go +++ b/runtime/sema/gen/testdata/composite_type_pragma/test.golden.go @@ -1,4 +1,4 @@ -// Code generated from testdata/composite-type-pragma.cdc. DO NOT EDIT. +// Code generated from testdata/composite_type_pragma/test.cdc. DO NOT EDIT. /* * Cadence - The resource-oriented smart contract programming language * @@ -17,14 +17,17 @@ * limitations under the License. */ -package sema +package composite_type_pragma -import "github.com/onflow/cadence/runtime/common" +import ( + "github.com/onflow/cadence/runtime/common" + "github.com/onflow/cadence/runtime/sema" +) const TestTypeName = "Test" -var TestType = func() *CompositeType { - var t = &CompositeType{ +var TestType = func() *sema.CompositeType { + var t = &sema.CompositeType{ Identifier: TestTypeName, Kind: common.CompositeKindStructure, ImportableBuiltin: false, diff --git a/runtime/sema/gen/testdata/constructor/test.cdc b/runtime/sema/gen/testdata/constructor/test.cdc new file mode 100644 index 0000000000..3c3881ee91 --- /dev/null +++ b/runtime/sema/gen/testdata/constructor/test.cdc @@ -0,0 +1,6 @@ +/// The Foo type +struct Foo { + + /// Constructs a new Foo + init(bar: Int) +} diff --git a/runtime/sema/gen/testdata/constructor/test.golden.go b/runtime/sema/gen/testdata/constructor/test.golden.go new file mode 100644 index 0000000000..3b2809675a --- /dev/null +++ b/runtime/sema/gen/testdata/constructor/test.golden.go @@ -0,0 +1,63 @@ +// Code generated from testdata/constructor/test.cdc. DO NOT EDIT. +/* + * Cadence - The resource-oriented smart contract programming language + * + * Copyright Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package constructor + +import ( + "github.com/onflow/cadence/runtime/common" + "github.com/onflow/cadence/runtime/sema" +) + +var FooTypeConstructorType = &sema.FunctionType{ + IsConstructor: true, + Parameters: []sema.Parameter{ + { + Identifier: "bar", + TypeAnnotation: sema.NewTypeAnnotation(sema.IntType), + }, + }, + ReturnTypeAnnotation: sema.NewTypeAnnotation( + FooType, + ), +} + +const FooTypeConstructorDocString = ` +Constructs a new Foo +` + +const FooTypeName = "Foo" + +var FooType = func() *sema.CompositeType { + var t = &sema.CompositeType{ + Identifier: FooTypeName, + Kind: common.CompositeKindStructure, + ImportableBuiltin: false, + HasComputedMembers: true, + } + + return t +}() + +func init() { + var members = []*sema.Member{} + + FooType.Members = sema.MembersAsMap(members) + FooType.Fields = sema.MembersFieldNames(members) + FooType.ConstructorParameters = FooTypeConstructorType.Parameters +} diff --git a/runtime/sema/gen/testdata/contract/test.cdc b/runtime/sema/gen/testdata/contract/test.cdc new file mode 100644 index 0000000000..51ba964699 --- /dev/null +++ b/runtime/sema/gen/testdata/contract/test.cdc @@ -0,0 +1,10 @@ +access(all) +contract Test { + + /// The Foo type + struct Foo { + + /// Constructs a new Foo + init(bar: Int) + } +} diff --git a/runtime/sema/gen/testdata/contract/test.golden.go b/runtime/sema/gen/testdata/contract/test.golden.go new file mode 100644 index 0000000000..1efdaeff66 --- /dev/null +++ b/runtime/sema/gen/testdata/contract/test.golden.go @@ -0,0 +1,93 @@ +// Code generated from testdata/contract/test.cdc. DO NOT EDIT. +/* + * Cadence - The resource-oriented smart contract programming language + * + * Copyright Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package contract + +import ( + "github.com/onflow/cadence/runtime/ast" + "github.com/onflow/cadence/runtime/common" + "github.com/onflow/cadence/runtime/sema" +) + +var Test_FooTypeConstructorType = &sema.FunctionType{ + IsConstructor: true, + Parameters: []sema.Parameter{ + { + Identifier: "bar", + TypeAnnotation: sema.NewTypeAnnotation(sema.IntType), + }, + }, + ReturnTypeAnnotation: sema.NewTypeAnnotation( + Test_FooType, + ), +} + +const Test_FooTypeConstructorDocString = ` +Constructs a new Foo +` + +const Test_FooTypeName = "Foo" + +var Test_FooType = func() *sema.CompositeType { + var t = &sema.CompositeType{ + Identifier: Test_FooTypeName, + Kind: common.CompositeKindStructure, + ImportableBuiltin: false, + HasComputedMembers: true, + } + + return t +}() + +func init() { + var members = []*sema.Member{} + + Test_FooType.Members = sema.MembersAsMap(members) + Test_FooType.Fields = sema.MembersFieldNames(members) + Test_FooType.ConstructorParameters = Test_FooTypeConstructorType.Parameters +} + +const TestTypeName = "Test" + +var TestType = func() *sema.CompositeType { + var t = &sema.CompositeType{ + Identifier: TestTypeName, + Kind: common.CompositeKindContract, + ImportableBuiltin: false, + HasComputedMembers: true, + } + + t.SetNestedType(Test_FooTypeName, Test_FooType) + return t +}() + +func init() { + var members = []*sema.Member{ + sema.NewUnmeteredConstructorMember( + TestType, + sema.PrimitiveAccess(ast.AccessAll), + Test_FooTypeName, + Test_FooTypeConstructorType, + Test_FooTypeConstructorDocString, + ), + } + + TestType.Members = sema.MembersAsMap(members) + TestType.Fields = sema.MembersFieldNames(members) +} diff --git a/runtime/sema/gen/testdata/docstrings/helper.go b/runtime/sema/gen/testdata/docstrings/helper.go new file mode 100644 index 0000000000..89877cfac0 --- /dev/null +++ b/runtime/sema/gen/testdata/docstrings/helper.go @@ -0,0 +1,23 @@ +/* + * Cadence - The resource-oriented smart contract programming language + * + * Copyright Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package docstrings + +import "github.com/onflow/cadence/runtime/sema" + +var DocstringsTypeTag sema.TypeTag diff --git a/runtime/sema/gen/testdata/docstrings.cdc b/runtime/sema/gen/testdata/docstrings/test.cdc similarity index 100% rename from runtime/sema/gen/testdata/docstrings.cdc rename to runtime/sema/gen/testdata/docstrings/test.cdc diff --git a/runtime/sema/gen/testdata/docstrings.golden.go b/runtime/sema/gen/testdata/docstrings/test.golden.go similarity index 66% rename from runtime/sema/gen/testdata/docstrings.golden.go rename to runtime/sema/gen/testdata/docstrings/test.golden.go index 68f4102b92..a35767c913 100644 --- a/runtime/sema/gen/testdata/docstrings.golden.go +++ b/runtime/sema/gen/testdata/docstrings/test.golden.go @@ -1,4 +1,4 @@ -// Code generated from testdata/docstrings.cdc. DO NOT EDIT. +// Code generated from testdata/docstrings/test.cdc. DO NOT EDIT. /* * Cadence - The resource-oriented smart contract programming language * @@ -17,13 +17,16 @@ * limitations under the License. */ -package sema +package docstrings -import "github.com/onflow/cadence/runtime/ast" +import ( + "github.com/onflow/cadence/runtime/ast" + "github.com/onflow/cadence/runtime/sema" +) const DocstringsTypeOwoFieldName = "owo" -var DocstringsTypeOwoFieldType = IntType +var DocstringsTypeOwoFieldType = sema.IntType const DocstringsTypeOwoFieldDocString = ` This is a 1-line docstring. @@ -31,8 +34,8 @@ This is a 1-line docstring. const DocstringsTypeUwuFieldName = "uwu" -var DocstringsTypeUwuFieldType = &VariableSizedType{ - Type: IntType, +var DocstringsTypeUwuFieldType = &sema.VariableSizedType{ + Type: sema.IntType, } const DocstringsTypeUwuFieldDocString = ` @@ -42,16 +45,16 @@ This is the second line. const DocstringsTypeNwnFunctionName = "nwn" -var DocstringsTypeNwnFunctionType = &FunctionType{ - Parameters: []Parameter{ +var DocstringsTypeNwnFunctionType = &sema.FunctionType{ + Parameters: []sema.Parameter{ { Identifier: "x", - TypeAnnotation: NewTypeAnnotation(IntType), + TypeAnnotation: sema.NewTypeAnnotation(sema.IntType), }, }, - ReturnTypeAnnotation: NewTypeAnnotation( - &OptionalType{ - Type: StringType, + ReturnTypeAnnotation: sema.NewTypeAnnotation( + &sema.OptionalType{ + Type: sema.StringType, }, ), } @@ -64,7 +67,7 @@ And the third line! const DocstringsTypeWithBlanksFieldName = "withBlanks" -var DocstringsTypeWithBlanksFieldType = IntType +var DocstringsTypeWithBlanksFieldType = sema.IntType const DocstringsTypeWithBlanksFieldDocString = ` This is a multiline docstring. @@ -74,9 +77,9 @@ There should be two newlines before this line! const DocstringsTypeIsSmolBeanFunctionName = "isSmolBean" -var DocstringsTypeIsSmolBeanFunctionType = &FunctionType{ - ReturnTypeAnnotation: NewTypeAnnotation( - BoolType, +var DocstringsTypeIsSmolBeanFunctionType = &sema.FunctionType{ + ReturnTypeAnnotation: sema.NewTypeAnnotation( + sema.BoolType, ), } @@ -87,10 +90,10 @@ These should be handled accordingly. const DocstringsTypeRunningOutOfIdeasFunctionName = "runningOutOfIdeas" -var DocstringsTypeRunningOutOfIdeasFunctionType = &FunctionType{ - ReturnTypeAnnotation: NewTypeAnnotation( - &OptionalType{ - Type: UInt64Type, +var DocstringsTypeRunningOutOfIdeasFunctionType = &sema.FunctionType{ + ReturnTypeAnnotation: sema.NewTypeAnnotation( + &sema.OptionalType{ + Type: sema.UInt64Type, }, ), } @@ -103,11 +106,11 @@ Look, I did it ` + "`again`" + `, wowie!! const DocstringsTypeName = "Docstrings" -var DocstringsType = &SimpleType{ +var DocstringsType = &sema.SimpleType{ Name: DocstringsTypeName, QualifiedName: DocstringsTypeName, TypeID: DocstringsTypeName, - tag: DocstringsTypeTag, + TypeTag: DocstringsTypeTag, IsResource: false, Storable: false, Equatable: false, @@ -118,49 +121,49 @@ var DocstringsType = &SimpleType{ } func init() { - DocstringsType.Members = func(t *SimpleType) map[string]MemberResolver { - return MembersAsResolvers([]*Member{ - NewUnmeteredFieldMember( + DocstringsType.Members = func(t *sema.SimpleType) map[string]sema.MemberResolver { + return sema.MembersAsResolvers([]*sema.Member{ + sema.NewUnmeteredFieldMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), ast.VariableKindConstant, DocstringsTypeOwoFieldName, DocstringsTypeOwoFieldType, DocstringsTypeOwoFieldDocString, ), - NewUnmeteredFieldMember( + sema.NewUnmeteredFieldMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), ast.VariableKindConstant, DocstringsTypeUwuFieldName, DocstringsTypeUwuFieldType, DocstringsTypeUwuFieldDocString, ), - NewUnmeteredFunctionMember( + sema.NewUnmeteredFunctionMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), DocstringsTypeNwnFunctionName, DocstringsTypeNwnFunctionType, DocstringsTypeNwnFunctionDocString, ), - NewUnmeteredFieldMember( + sema.NewUnmeteredFieldMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), ast.VariableKindConstant, DocstringsTypeWithBlanksFieldName, DocstringsTypeWithBlanksFieldType, DocstringsTypeWithBlanksFieldDocString, ), - NewUnmeteredFunctionMember( + sema.NewUnmeteredFunctionMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), DocstringsTypeIsSmolBeanFunctionName, DocstringsTypeIsSmolBeanFunctionType, DocstringsTypeIsSmolBeanFunctionDocString, ), - NewUnmeteredFunctionMember( + sema.NewUnmeteredFunctionMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), DocstringsTypeRunningOutOfIdeasFunctionName, DocstringsTypeRunningOutOfIdeasFunctionType, DocstringsTypeRunningOutOfIdeasFunctionDocString, diff --git a/runtime/sema/gen/testdata/entitlement.cdc b/runtime/sema/gen/testdata/entitlement/test.cdc similarity index 100% rename from runtime/sema/gen/testdata/entitlement.cdc rename to runtime/sema/gen/testdata/entitlement/test.cdc diff --git a/runtime/sema/gen/testdata/entitlement.golden.go b/runtime/sema/gen/testdata/entitlement/test.golden.go similarity index 58% rename from runtime/sema/gen/testdata/entitlement.golden.go rename to runtime/sema/gen/testdata/entitlement/test.golden.go index 0296d081f3..1d44250ceb 100644 --- a/runtime/sema/gen/testdata/entitlement.golden.go +++ b/runtime/sema/gen/testdata/entitlement/test.golden.go @@ -1,4 +1,4 @@ -// Code generated from testdata/entitlement.cdc. DO NOT EDIT. +// Code generated from testdata/entitlement/test.cdc. DO NOT EDIT. /* * Cadence - The resource-oriented smart contract programming language * @@ -17,32 +17,34 @@ * limitations under the License. */ -package sema +package entitlement -var FooType = &EntitlementType{ +import "github.com/onflow/cadence/runtime/sema" + +var FooType = &sema.EntitlementType{ Identifier: "Foo", } -var BarType = &EntitlementType{ +var BarType = &sema.EntitlementType{ Identifier: "Bar", } -var BazType = &EntitlementMapType{ +var BazType = &sema.EntitlementMapType{ Identifier: "Baz", IncludesIdentity: false, - Relations: []EntitlementRelation{ - EntitlementRelation{ + Relations: []sema.EntitlementRelation{ + sema.EntitlementRelation{ Input: FooType, Output: BarType, }, }, } -var QuxType = &EntitlementMapType{ +var QuxType = &sema.EntitlementMapType{ Identifier: "Qux", IncludesIdentity: true, - Relations: []EntitlementRelation{ - EntitlementRelation{ + Relations: []sema.EntitlementRelation{ + sema.EntitlementRelation{ Input: FooType, Output: BarType, }, @@ -50,12 +52,8 @@ var QuxType = &EntitlementMapType{ } func init() { - BuiltinEntitlementMappings[BazType.Identifier] = BazType - addToBaseActivation(BazType) - BuiltinEntitlementMappings[QuxType.Identifier] = QuxType - addToBaseActivation(QuxType) - BuiltinEntitlements[FooType.Identifier] = FooType - addToBaseActivation(FooType) - BuiltinEntitlements[BarType.Identifier] = BarType - addToBaseActivation(BarType) + sema.BuiltinEntitlementMappings[BazType.Identifier] = BazType + sema.BuiltinEntitlementMappings[QuxType.Identifier] = QuxType + sema.BuiltinEntitlements[FooType.Identifier] = FooType + sema.BuiltinEntitlements[BarType.Identifier] = BarType } diff --git a/runtime/sema/gen/testdata/equatable/helper.go b/runtime/sema/gen/testdata/equatable/helper.go new file mode 100644 index 0000000000..1fe9bc6a2a --- /dev/null +++ b/runtime/sema/gen/testdata/equatable/helper.go @@ -0,0 +1,23 @@ +/* + * Cadence - The resource-oriented smart contract programming language + * + * Copyright Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package equatable + +import "github.com/onflow/cadence/runtime/sema" + +var TestTypeTag sema.TypeTag diff --git a/runtime/sema/gen/testdata/equatable.cdc b/runtime/sema/gen/testdata/equatable/test.cdc similarity index 100% rename from runtime/sema/gen/testdata/equatable.cdc rename to runtime/sema/gen/testdata/equatable/test.cdc diff --git a/runtime/sema/gen/testdata/equatable.golden.go b/runtime/sema/gen/testdata/equatable/test.golden.go similarity index 83% rename from runtime/sema/gen/testdata/equatable.golden.go rename to runtime/sema/gen/testdata/equatable/test.golden.go index 82320957ee..e102e7e6de 100644 --- a/runtime/sema/gen/testdata/equatable.golden.go +++ b/runtime/sema/gen/testdata/equatable/test.golden.go @@ -1,4 +1,4 @@ -// Code generated from testdata/equatable.cdc. DO NOT EDIT. +// Code generated from testdata/equatable/test.cdc. DO NOT EDIT. /* * Cadence - The resource-oriented smart contract programming language * @@ -17,15 +17,17 @@ * limitations under the License. */ -package sema +package equatable + +import "github.com/onflow/cadence/runtime/sema" const TestTypeName = "Test" -var TestType = &SimpleType{ +var TestType = &sema.SimpleType{ Name: TestTypeName, QualifiedName: TestTypeName, TypeID: TestTypeName, - tag: TestTypeTag, + TypeTag: TestTypeTag, IsResource: false, Storable: false, Equatable: true, diff --git a/runtime/sema/gen/testdata/exportable/helper.go b/runtime/sema/gen/testdata/exportable/helper.go new file mode 100644 index 0000000000..92baaf371c --- /dev/null +++ b/runtime/sema/gen/testdata/exportable/helper.go @@ -0,0 +1,23 @@ +/* + * Cadence - The resource-oriented smart contract programming language + * + * Copyright Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package exportable + +import "github.com/onflow/cadence/runtime/sema" + +var TestTypeTag sema.TypeTag diff --git a/runtime/sema/gen/testdata/exportable.cdc b/runtime/sema/gen/testdata/exportable/test.cdc similarity index 100% rename from runtime/sema/gen/testdata/exportable.cdc rename to runtime/sema/gen/testdata/exportable/test.cdc diff --git a/runtime/sema/gen/testdata/exportable.golden.go b/runtime/sema/gen/testdata/exportable/test.golden.go similarity index 82% rename from runtime/sema/gen/testdata/exportable.golden.go rename to runtime/sema/gen/testdata/exportable/test.golden.go index db6afd0593..3124209d4a 100644 --- a/runtime/sema/gen/testdata/exportable.golden.go +++ b/runtime/sema/gen/testdata/exportable/test.golden.go @@ -1,4 +1,4 @@ -// Code generated from testdata/exportable.cdc. DO NOT EDIT. +// Code generated from testdata/exportable/test.cdc. DO NOT EDIT. /* * Cadence - The resource-oriented smart contract programming language * @@ -17,15 +17,17 @@ * limitations under the License. */ -package sema +package exportable + +import "github.com/onflow/cadence/runtime/sema" const TestTypeName = "Test" -var TestType = &SimpleType{ +var TestType = &sema.SimpleType{ Name: TestTypeName, QualifiedName: TestTypeName, TypeID: TestTypeName, - tag: TestTypeTag, + TypeTag: TestTypeTag, IsResource: false, Storable: false, Equatable: false, diff --git a/runtime/sema/gen/testdata/fields/helper.go b/runtime/sema/gen/testdata/fields/helper.go new file mode 100644 index 0000000000..0fbaa3f0f8 --- /dev/null +++ b/runtime/sema/gen/testdata/fields/helper.go @@ -0,0 +1,26 @@ +/* + * Cadence - The resource-oriented smart contract programming language + * + * Copyright Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package fields + +import "github.com/onflow/cadence/runtime/sema" + +var TestTypeTag sema.TypeTag +var FooType = &sema.CapabilityType{} +var BarType *sema.InterfaceType +var BazType *sema.InterfaceType diff --git a/runtime/sema/gen/testdata/fields.cdc b/runtime/sema/gen/testdata/fields/test.cdc similarity index 99% rename from runtime/sema/gen/testdata/fields.cdc rename to runtime/sema/gen/testdata/fields/test.cdc index 1cf74e4f96..2f5338d1e9 100644 --- a/runtime/sema/gen/testdata/fields.cdc +++ b/runtime/sema/gen/testdata/fields/test.cdc @@ -1,3 +1,4 @@ + access(all) struct Test { /// This is a test integer. access(all) let testInt: UInt64 diff --git a/runtime/sema/gen/testdata/fields.golden.go b/runtime/sema/gen/testdata/fields/test.golden.go similarity index 67% rename from runtime/sema/gen/testdata/fields.golden.go rename to runtime/sema/gen/testdata/fields/test.golden.go index f4af42f973..950c618e93 100644 --- a/runtime/sema/gen/testdata/fields.golden.go +++ b/runtime/sema/gen/testdata/fields/test.golden.go @@ -1,4 +1,4 @@ -// Code generated from testdata/fields.cdc. DO NOT EDIT. +// Code generated from testdata/fields/test.cdc. DO NOT EDIT. /* * Cadence - The resource-oriented smart contract programming language * @@ -17,13 +17,16 @@ * limitations under the License. */ -package sema +package fields -import "github.com/onflow/cadence/runtime/ast" +import ( + "github.com/onflow/cadence/runtime/ast" + "github.com/onflow/cadence/runtime/sema" +) const TestTypeTestIntFieldName = "testInt" -var TestTypeTestIntFieldType = UInt64Type +var TestTypeTestIntFieldType = sema.UInt64Type const TestTypeTestIntFieldDocString = ` This is a test integer. @@ -31,8 +34,8 @@ This is a test integer. const TestTypeTestOptIntFieldName = "testOptInt" -var TestTypeTestOptIntFieldType = &OptionalType{ - Type: UInt64Type, +var TestTypeTestOptIntFieldType = &sema.OptionalType{ + Type: sema.UInt64Type, } const TestTypeTestOptIntFieldDocString = ` @@ -41,9 +44,9 @@ This is a test optional integer. const TestTypeTestRefIntFieldName = "testRefInt" -var TestTypeTestRefIntFieldType = &ReferenceType{ - Type: UInt64Type, - Authorization: UnauthorizedAccess, +var TestTypeTestRefIntFieldType = &sema.ReferenceType{ + Type: sema.UInt64Type, + Authorization: sema.UnauthorizedAccess, } const TestTypeTestRefIntFieldDocString = ` @@ -52,8 +55,8 @@ This is a test integer reference. const TestTypeTestVarIntsFieldName = "testVarInts" -var TestTypeTestVarIntsFieldType = &VariableSizedType{ - Type: UInt64Type, +var TestTypeTestVarIntsFieldType = &sema.VariableSizedType{ + Type: sema.UInt64Type, } const TestTypeTestVarIntsFieldDocString = ` @@ -62,8 +65,8 @@ This is a test variable-sized integer array. const TestTypeTestConstIntsFieldName = "testConstInts" -var TestTypeTestConstIntsFieldType = &ConstantSizedType{ - Type: UInt64Type, +var TestTypeTestConstIntsFieldType = &sema.ConstantSizedType{ + Type: sema.UInt64Type, Size: 2, } @@ -73,9 +76,9 @@ This is a test constant-sized integer array. const TestTypeTestIntDictFieldName = "testIntDict" -var TestTypeTestIntDictFieldType = &DictionaryType{ - KeyType: UInt64Type, - ValueType: BoolType, +var TestTypeTestIntDictFieldType = &sema.DictionaryType{ + KeyType: sema.UInt64Type, + ValueType: sema.BoolType, } const TestTypeTestIntDictFieldDocString = ` @@ -84,7 +87,7 @@ This is a test integer dictionary. const TestTypeTestParamFieldName = "testParam" -var TestTypeTestParamFieldType = MustInstantiate( +var TestTypeTestParamFieldType = sema.MustInstantiate( FooType, BarType, ) @@ -95,7 +98,7 @@ This is a test parameterized-type field. const TestTypeTestAddressFieldName = "testAddress" -var TestTypeTestAddressFieldType = TheAddressType +var TestTypeTestAddressFieldType = sema.TheAddressType const TestTypeTestAddressFieldDocString = ` This is a test address field. @@ -103,7 +106,7 @@ This is a test address field. const TestTypeTestTypeFieldName = "testType" -var TestTypeTestTypeFieldType = MetaType +var TestTypeTestTypeFieldType = sema.MetaType const TestTypeTestTypeFieldDocString = ` This is a test type field. @@ -111,7 +114,7 @@ This is a test type field. const TestTypeTestCapFieldName = "testCap" -var TestTypeTestCapFieldType = &CapabilityType{} +var TestTypeTestCapFieldType = &sema.CapabilityType{} const TestTypeTestCapFieldDocString = ` This is a test unparameterized capability field. @@ -119,9 +122,9 @@ This is a test unparameterized capability field. const TestTypeTestCapIntFieldName = "testCapInt" -var TestTypeTestCapIntFieldType = MustInstantiate( - &CapabilityType{}, - IntType, +var TestTypeTestCapIntFieldType = sema.MustInstantiate( + &sema.CapabilityType{}, + sema.IntType, ) const TestTypeTestCapIntFieldDocString = ` @@ -130,8 +133,8 @@ This is a test parameterized capability field. const TestTypeTestIntersectionWithoutTypeFieldName = "testIntersectionWithoutType" -var TestTypeTestIntersectionWithoutTypeFieldType = &IntersectionType{ - Types: []*InterfaceType{BarType, BazType}, +var TestTypeTestIntersectionWithoutTypeFieldType = &sema.IntersectionType{ + Types: []*sema.InterfaceType{BarType, BazType}, } const TestTypeTestIntersectionWithoutTypeFieldDocString = ` @@ -140,11 +143,11 @@ This is a test intersection type (without type) field. const TestTypeName = "Test" -var TestType = &SimpleType{ +var TestType = &sema.SimpleType{ Name: TestTypeName, QualifiedName: TestTypeName, TypeID: TestTypeName, - tag: TestTypeTag, + TypeTag: TestTypeTag, IsResource: false, Storable: false, Equatable: false, @@ -155,99 +158,99 @@ var TestType = &SimpleType{ } func init() { - TestType.Members = func(t *SimpleType) map[string]MemberResolver { - return MembersAsResolvers([]*Member{ - NewUnmeteredFieldMember( + TestType.Members = func(t *sema.SimpleType) map[string]sema.MemberResolver { + return sema.MembersAsResolvers([]*sema.Member{ + sema.NewUnmeteredFieldMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), ast.VariableKindConstant, TestTypeTestIntFieldName, TestTypeTestIntFieldType, TestTypeTestIntFieldDocString, ), - NewUnmeteredFieldMember( + sema.NewUnmeteredFieldMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), ast.VariableKindConstant, TestTypeTestOptIntFieldName, TestTypeTestOptIntFieldType, TestTypeTestOptIntFieldDocString, ), - NewUnmeteredFieldMember( + sema.NewUnmeteredFieldMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), ast.VariableKindConstant, TestTypeTestRefIntFieldName, TestTypeTestRefIntFieldType, TestTypeTestRefIntFieldDocString, ), - NewUnmeteredFieldMember( + sema.NewUnmeteredFieldMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), ast.VariableKindConstant, TestTypeTestVarIntsFieldName, TestTypeTestVarIntsFieldType, TestTypeTestVarIntsFieldDocString, ), - NewUnmeteredFieldMember( + sema.NewUnmeteredFieldMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), ast.VariableKindConstant, TestTypeTestConstIntsFieldName, TestTypeTestConstIntsFieldType, TestTypeTestConstIntsFieldDocString, ), - NewUnmeteredFieldMember( + sema.NewUnmeteredFieldMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), ast.VariableKindConstant, TestTypeTestIntDictFieldName, TestTypeTestIntDictFieldType, TestTypeTestIntDictFieldDocString, ), - NewUnmeteredFieldMember( + sema.NewUnmeteredFieldMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), ast.VariableKindConstant, TestTypeTestParamFieldName, TestTypeTestParamFieldType, TestTypeTestParamFieldDocString, ), - NewUnmeteredFieldMember( + sema.NewUnmeteredFieldMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), ast.VariableKindConstant, TestTypeTestAddressFieldName, TestTypeTestAddressFieldType, TestTypeTestAddressFieldDocString, ), - NewUnmeteredFieldMember( + sema.NewUnmeteredFieldMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), ast.VariableKindConstant, TestTypeTestTypeFieldName, TestTypeTestTypeFieldType, TestTypeTestTypeFieldDocString, ), - NewUnmeteredFieldMember( + sema.NewUnmeteredFieldMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), ast.VariableKindConstant, TestTypeTestCapFieldName, TestTypeTestCapFieldType, TestTypeTestCapFieldDocString, ), - NewUnmeteredFieldMember( + sema.NewUnmeteredFieldMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), ast.VariableKindConstant, TestTypeTestCapIntFieldName, TestTypeTestCapIntFieldType, TestTypeTestCapIntFieldDocString, ), - NewUnmeteredFieldMember( + sema.NewUnmeteredFieldMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), ast.VariableKindConstant, TestTypeTestIntersectionWithoutTypeFieldName, TestTypeTestIntersectionWithoutTypeFieldType, diff --git a/runtime/sema/gen/testdata/functions/helper.go b/runtime/sema/gen/testdata/functions/helper.go new file mode 100644 index 0000000000..eb10cbad92 --- /dev/null +++ b/runtime/sema/gen/testdata/functions/helper.go @@ -0,0 +1,23 @@ +/* + * Cadence - The resource-oriented smart contract programming language + * + * Copyright Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package functions + +import "github.com/onflow/cadence/runtime/sema" + +var TestTypeTag sema.TypeTag diff --git a/runtime/sema/gen/testdata/functions.cdc b/runtime/sema/gen/testdata/functions/test.cdc similarity index 100% rename from runtime/sema/gen/testdata/functions.cdc rename to runtime/sema/gen/testdata/functions/test.cdc diff --git a/runtime/sema/gen/testdata/functions.golden.go b/runtime/sema/gen/testdata/functions/test.golden.go similarity index 57% rename from runtime/sema/gen/testdata/functions.golden.go rename to runtime/sema/gen/testdata/functions/test.golden.go index 41226f8238..2c22638b28 100644 --- a/runtime/sema/gen/testdata/functions.golden.go +++ b/runtime/sema/gen/testdata/functions/test.golden.go @@ -1,4 +1,4 @@ -// Code generated from testdata/functions.cdc. DO NOT EDIT. +// Code generated from testdata/functions/test.cdc. DO NOT EDIT. /* * Cadence - The resource-oriented smart contract programming language * @@ -17,15 +17,18 @@ * limitations under the License. */ -package sema +package functions -import "github.com/onflow/cadence/runtime/ast" +import ( + "github.com/onflow/cadence/runtime/ast" + "github.com/onflow/cadence/runtime/sema" +) const TestTypeNothingFunctionName = "nothing" -var TestTypeNothingFunctionType = &FunctionType{ - ReturnTypeAnnotation: NewTypeAnnotation( - VoidType, +var TestTypeNothingFunctionType = &sema.FunctionType{ + ReturnTypeAnnotation: sema.NewTypeAnnotation( + sema.VoidType, ), } @@ -35,20 +38,20 @@ This is a test function. const TestTypeParamsFunctionName = "params" -var TestTypeParamsFunctionType = &FunctionType{ - Parameters: []Parameter{ +var TestTypeParamsFunctionType = &sema.FunctionType{ + Parameters: []sema.Parameter{ { Identifier: "a", - TypeAnnotation: NewTypeAnnotation(IntType), + TypeAnnotation: sema.NewTypeAnnotation(sema.IntType), }, { - Label: ArgumentLabelNotRequired, + Label: sema.ArgumentLabelNotRequired, Identifier: "b", - TypeAnnotation: NewTypeAnnotation(StringType), + TypeAnnotation: sema.NewTypeAnnotation(sema.StringType), }, }, - ReturnTypeAnnotation: NewTypeAnnotation( - VoidType, + ReturnTypeAnnotation: sema.NewTypeAnnotation( + sema.VoidType, ), } @@ -58,9 +61,9 @@ This is a test function with parameters. const TestTypeReturnBoolFunctionName = "returnBool" -var TestTypeReturnBoolFunctionType = &FunctionType{ - ReturnTypeAnnotation: NewTypeAnnotation( - BoolType, +var TestTypeReturnBoolFunctionType = &sema.FunctionType{ + ReturnTypeAnnotation: sema.NewTypeAnnotation( + sema.BoolType, ), } @@ -70,20 +73,20 @@ This is a test function with a return type. const TestTypeParamsAndReturnFunctionName = "paramsAndReturn" -var TestTypeParamsAndReturnFunctionType = &FunctionType{ - Parameters: []Parameter{ +var TestTypeParamsAndReturnFunctionType = &sema.FunctionType{ + Parameters: []sema.Parameter{ { Identifier: "a", - TypeAnnotation: NewTypeAnnotation(IntType), + TypeAnnotation: sema.NewTypeAnnotation(sema.IntType), }, { - Label: ArgumentLabelNotRequired, + Label: sema.ArgumentLabelNotRequired, Identifier: "b", - TypeAnnotation: NewTypeAnnotation(StringType), + TypeAnnotation: sema.NewTypeAnnotation(sema.StringType), }, }, - ReturnTypeAnnotation: NewTypeAnnotation( - BoolType, + ReturnTypeAnnotation: sema.NewTypeAnnotation( + sema.BoolType, ), } @@ -93,16 +96,16 @@ This is a test function with parameters and a return type. const TestTypeTypeParamFunctionName = "typeParam" -var TestTypeTypeParamFunctionTypeParameterT = &TypeParameter{ +var TestTypeTypeParamFunctionTypeParameterT = &sema.TypeParameter{ Name: "T", } -var TestTypeTypeParamFunctionType = &FunctionType{ - TypeParameters: []*TypeParameter{ +var TestTypeTypeParamFunctionType = &sema.FunctionType{ + TypeParameters: []*sema.TypeParameter{ TestTypeTypeParamFunctionTypeParameterT, }, - ReturnTypeAnnotation: NewTypeAnnotation( - VoidType, + ReturnTypeAnnotation: sema.NewTypeAnnotation( + sema.VoidType, ), } @@ -112,20 +115,20 @@ This is a test function with a type parameter. const TestTypeTypeParamWithBoundFunctionName = "typeParamWithBound" -var TestTypeTypeParamWithBoundFunctionTypeParameterT = &TypeParameter{ +var TestTypeTypeParamWithBoundFunctionTypeParameterT = &sema.TypeParameter{ Name: "T", - TypeBound: &ReferenceType{ - Type: AnyType, - Authorization: UnauthorizedAccess, + TypeBound: &sema.ReferenceType{ + Type: sema.AnyType, + Authorization: sema.UnauthorizedAccess, }, } -var TestTypeTypeParamWithBoundFunctionType = &FunctionType{ - TypeParameters: []*TypeParameter{ +var TestTypeTypeParamWithBoundFunctionType = &sema.FunctionType{ + TypeParameters: []*sema.TypeParameter{ TestTypeTypeParamWithBoundFunctionTypeParameterT, }, - ReturnTypeAnnotation: NewTypeAnnotation( - VoidType, + ReturnTypeAnnotation: sema.NewTypeAnnotation( + sema.VoidType, ), } @@ -135,24 +138,24 @@ This is a test function with a type parameter and a type bound. const TestTypeTypeParamWithBoundAndParamFunctionName = "typeParamWithBoundAndParam" -var TestTypeTypeParamWithBoundAndParamFunctionTypeParameterT = &TypeParameter{ +var TestTypeTypeParamWithBoundAndParamFunctionTypeParameterT = &sema.TypeParameter{ Name: "T", } -var TestTypeTypeParamWithBoundAndParamFunctionType = &FunctionType{ - TypeParameters: []*TypeParameter{ +var TestTypeTypeParamWithBoundAndParamFunctionType = &sema.FunctionType{ + TypeParameters: []*sema.TypeParameter{ TestTypeTypeParamWithBoundAndParamFunctionTypeParameterT, }, - Parameters: []Parameter{ + Parameters: []sema.Parameter{ { Identifier: "t", - TypeAnnotation: NewTypeAnnotation(&GenericType{ + TypeAnnotation: sema.NewTypeAnnotation(&sema.GenericType{ TypeParameter: TestTypeTypeParamWithBoundAndParamFunctionTypeParameterT, }), }, }, - ReturnTypeAnnotation: NewTypeAnnotation( - VoidType, + ReturnTypeAnnotation: sema.NewTypeAnnotation( + sema.VoidType, ), } @@ -162,10 +165,10 @@ This is a test function with a type parameter and a parameter using it. const TestTypeViewFunctionFunctionName = "viewFunction" -var TestTypeViewFunctionFunctionType = &FunctionType{ - Purity: FunctionPurityView, - ReturnTypeAnnotation: NewTypeAnnotation( - VoidType, +var TestTypeViewFunctionFunctionType = &sema.FunctionType{ + Purity: sema.FunctionPurityView, + ReturnTypeAnnotation: sema.NewTypeAnnotation( + sema.VoidType, ), } @@ -175,11 +178,11 @@ This is a function with 'view' modifier const TestTypeName = "Test" -var TestType = &SimpleType{ +var TestType = &sema.SimpleType{ Name: TestTypeName, QualifiedName: TestTypeName, TypeID: TestTypeName, - tag: TestTypeTag, + TypeTag: TestTypeTag, IsResource: false, Storable: false, Equatable: false, @@ -190,60 +193,60 @@ var TestType = &SimpleType{ } func init() { - TestType.Members = func(t *SimpleType) map[string]MemberResolver { - return MembersAsResolvers([]*Member{ - NewUnmeteredFunctionMember( + TestType.Members = func(t *sema.SimpleType) map[string]sema.MemberResolver { + return sema.MembersAsResolvers([]*sema.Member{ + sema.NewUnmeteredFunctionMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), TestTypeNothingFunctionName, TestTypeNothingFunctionType, TestTypeNothingFunctionDocString, ), - NewUnmeteredFunctionMember( + sema.NewUnmeteredFunctionMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), TestTypeParamsFunctionName, TestTypeParamsFunctionType, TestTypeParamsFunctionDocString, ), - NewUnmeteredFunctionMember( + sema.NewUnmeteredFunctionMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), TestTypeReturnBoolFunctionName, TestTypeReturnBoolFunctionType, TestTypeReturnBoolFunctionDocString, ), - NewUnmeteredFunctionMember( + sema.NewUnmeteredFunctionMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), TestTypeParamsAndReturnFunctionName, TestTypeParamsAndReturnFunctionType, TestTypeParamsAndReturnFunctionDocString, ), - NewUnmeteredFunctionMember( + sema.NewUnmeteredFunctionMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), TestTypeTypeParamFunctionName, TestTypeTypeParamFunctionType, TestTypeTypeParamFunctionDocString, ), - NewUnmeteredFunctionMember( + sema.NewUnmeteredFunctionMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), TestTypeTypeParamWithBoundFunctionName, TestTypeTypeParamWithBoundFunctionType, TestTypeTypeParamWithBoundFunctionDocString, ), - NewUnmeteredFunctionMember( + sema.NewUnmeteredFunctionMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), TestTypeTypeParamWithBoundAndParamFunctionName, TestTypeTypeParamWithBoundAndParamFunctionType, TestTypeTypeParamWithBoundAndParamFunctionDocString, ), - NewUnmeteredFunctionMember( + sema.NewUnmeteredFunctionMember( t, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), TestTypeViewFunctionFunctionName, TestTypeViewFunctionFunctionType, TestTypeViewFunctionFunctionDocString, diff --git a/runtime/sema/gen/testdata/importable/helper.go b/runtime/sema/gen/testdata/importable/helper.go new file mode 100644 index 0000000000..6a02e2c7c5 --- /dev/null +++ b/runtime/sema/gen/testdata/importable/helper.go @@ -0,0 +1,23 @@ +/* + * Cadence - The resource-oriented smart contract programming language + * + * Copyright Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package importable + +import "github.com/onflow/cadence/runtime/sema" + +var TestTypeTag sema.TypeTag diff --git a/runtime/sema/gen/testdata/importable.cdc b/runtime/sema/gen/testdata/importable/test.cdc similarity index 100% rename from runtime/sema/gen/testdata/importable.cdc rename to runtime/sema/gen/testdata/importable/test.cdc diff --git a/runtime/sema/gen/testdata/importable.golden.go b/runtime/sema/gen/testdata/importable/test.golden.go similarity index 82% rename from runtime/sema/gen/testdata/importable.golden.go rename to runtime/sema/gen/testdata/importable/test.golden.go index 39496013d4..243be9b153 100644 --- a/runtime/sema/gen/testdata/importable.golden.go +++ b/runtime/sema/gen/testdata/importable/test.golden.go @@ -1,4 +1,4 @@ -// Code generated from testdata/importable.cdc. DO NOT EDIT. +// Code generated from testdata/importable/test.cdc. DO NOT EDIT. /* * Cadence - The resource-oriented smart contract programming language * @@ -17,15 +17,17 @@ * limitations under the License. */ -package sema +package importable + +import "github.com/onflow/cadence/runtime/sema" const TestTypeName = "Test" -var TestType = &SimpleType{ +var TestType = &sema.SimpleType{ Name: TestTypeName, QualifiedName: TestTypeName, TypeID: TestTypeName, - tag: TestTypeTag, + TypeTag: TestTypeTag, IsResource: false, Storable: false, Equatable: false, diff --git a/runtime/sema/gen/testdata/member_accessible/helper.go b/runtime/sema/gen/testdata/member_accessible/helper.go new file mode 100644 index 0000000000..2632d04b5c --- /dev/null +++ b/runtime/sema/gen/testdata/member_accessible/helper.go @@ -0,0 +1,23 @@ +/* + * Cadence - The resource-oriented smart contract programming language + * + * Copyright Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package member_accessible + +import "github.com/onflow/cadence/runtime/sema" + +var TestTypeTag sema.TypeTag diff --git a/runtime/sema/gen/testdata/member_accessible.cdc b/runtime/sema/gen/testdata/member_accessible/test.cdc similarity index 100% rename from runtime/sema/gen/testdata/member_accessible.cdc rename to runtime/sema/gen/testdata/member_accessible/test.cdc diff --git a/runtime/sema/gen/testdata/member_accessible.golden.go b/runtime/sema/gen/testdata/member_accessible/test.golden.go similarity index 81% rename from runtime/sema/gen/testdata/member_accessible.golden.go rename to runtime/sema/gen/testdata/member_accessible/test.golden.go index d3553ebafd..ec49013df0 100644 --- a/runtime/sema/gen/testdata/member_accessible.golden.go +++ b/runtime/sema/gen/testdata/member_accessible/test.golden.go @@ -1,4 +1,4 @@ -// Code generated from testdata/member_accessible.cdc. DO NOT EDIT. +// Code generated from testdata/member_accessible/test.cdc. DO NOT EDIT. /* * Cadence - The resource-oriented smart contract programming language * @@ -17,15 +17,17 @@ * limitations under the License. */ -package sema +package member_accessible + +import "github.com/onflow/cadence/runtime/sema" const TestTypeName = "Test" -var TestType = &SimpleType{ +var TestType = &sema.SimpleType{ Name: TestTypeName, QualifiedName: TestTypeName, TypeID: TestTypeName, - tag: TestTypeTag, + TypeTag: TestTypeTag, IsResource: false, Storable: false, Equatable: false, diff --git a/runtime/sema/gen/testdata/nested.cdc b/runtime/sema/gen/testdata/nested/test.cdc similarity index 100% rename from runtime/sema/gen/testdata/nested.cdc rename to runtime/sema/gen/testdata/nested/test.cdc diff --git a/runtime/sema/gen/testdata/nested.golden.go b/runtime/sema/gen/testdata/nested/test.golden.go similarity index 65% rename from runtime/sema/gen/testdata/nested.golden.go rename to runtime/sema/gen/testdata/nested/test.golden.go index 73c94c99c1..d5a1058aa0 100644 --- a/runtime/sema/gen/testdata/nested.golden.go +++ b/runtime/sema/gen/testdata/nested/test.golden.go @@ -1,4 +1,4 @@ -// Code generated from testdata/nested.cdc. DO NOT EDIT. +// Code generated from testdata/nested/test.cdc. DO NOT EDIT. /* * Cadence - The resource-oriented smart contract programming language * @@ -17,18 +17,19 @@ * limitations under the License. */ -package sema +package nested import ( "github.com/onflow/cadence/runtime/ast" "github.com/onflow/cadence/runtime/common" + "github.com/onflow/cadence/runtime/sema" ) const FooTypeFooFunctionName = "foo" -var FooTypeFooFunctionType = &FunctionType{ - ReturnTypeAnnotation: NewTypeAnnotation( - VoidType, +var FooTypeFooFunctionType = &sema.FunctionType{ + ReturnTypeAnnotation: sema.NewTypeAnnotation( + sema.VoidType, ), } @@ -46,9 +47,9 @@ Bar const Foo_BarTypeBarFunctionName = "bar" -var Foo_BarTypeBarFunctionType = &FunctionType{ - ReturnTypeAnnotation: NewTypeAnnotation( - VoidType, +var Foo_BarTypeBarFunctionType = &sema.FunctionType{ + ReturnTypeAnnotation: sema.NewTypeAnnotation( + sema.VoidType, ), } @@ -58,8 +59,8 @@ bar const Foo_BarTypeName = "Bar" -var Foo_BarType = func() *CompositeType { - var t = &CompositeType{ +var Foo_BarType = func() *sema.CompositeType { + var t = &sema.CompositeType{ Identifier: Foo_BarTypeName, Kind: common.CompositeKindStructure, ImportableBuiltin: false, @@ -70,24 +71,24 @@ var Foo_BarType = func() *CompositeType { }() func init() { - var members = []*Member{ - NewUnmeteredFunctionMember( + var members = []*sema.Member{ + sema.NewUnmeteredFunctionMember( Foo_BarType, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), Foo_BarTypeBarFunctionName, Foo_BarTypeBarFunctionType, Foo_BarTypeBarFunctionDocString, ), } - Foo_BarType.Members = MembersAsMap(members) - Foo_BarType.Fields = MembersFieldNames(members) + Foo_BarType.Members = sema.MembersAsMap(members) + Foo_BarType.Fields = sema.MembersFieldNames(members) } const FooTypeName = "Foo" -var FooType = func() *CompositeType { - var t = &CompositeType{ +var FooType = func() *sema.CompositeType { + var t = &sema.CompositeType{ Identifier: FooTypeName, Kind: common.CompositeKindStructure, ImportableBuiltin: false, @@ -99,17 +100,17 @@ var FooType = func() *CompositeType { }() func init() { - var members = []*Member{ - NewUnmeteredFunctionMember( + var members = []*sema.Member{ + sema.NewUnmeteredFunctionMember( FooType, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), FooTypeFooFunctionName, FooTypeFooFunctionType, FooTypeFooFunctionDocString, ), - NewUnmeteredFieldMember( + sema.NewUnmeteredFieldMember( FooType, - PrimitiveAccess(ast.AccessAll), + sema.PrimitiveAccess(ast.AccessAll), ast.VariableKindConstant, FooTypeBarFieldName, FooTypeBarFieldType, @@ -117,6 +118,6 @@ func init() { ), } - FooType.Members = MembersAsMap(members) - FooType.Fields = MembersFieldNames(members) + FooType.Members = sema.MembersAsMap(members) + FooType.Fields = sema.MembersFieldNames(members) } diff --git a/runtime/sema/gen/testdata/simple_resource/helper.go b/runtime/sema/gen/testdata/simple_resource/helper.go new file mode 100644 index 0000000000..16de616169 --- /dev/null +++ b/runtime/sema/gen/testdata/simple_resource/helper.go @@ -0,0 +1,23 @@ +/* + * Cadence - The resource-oriented smart contract programming language + * + * Copyright Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package simple_resource + +import "github.com/onflow/cadence/runtime/sema" + +var TestTypeTag sema.TypeTag diff --git a/runtime/sema/gen/testdata/simple-resource.cdc b/runtime/sema/gen/testdata/simple_resource/test.cdc similarity index 100% rename from runtime/sema/gen/testdata/simple-resource.cdc rename to runtime/sema/gen/testdata/simple_resource/test.cdc diff --git a/runtime/sema/gen/testdata/simple-resource.golden.go b/runtime/sema/gen/testdata/simple_resource/test.golden.go similarity index 82% rename from runtime/sema/gen/testdata/simple-resource.golden.go rename to runtime/sema/gen/testdata/simple_resource/test.golden.go index 53ee6c24f7..a6876b92ce 100644 --- a/runtime/sema/gen/testdata/simple-resource.golden.go +++ b/runtime/sema/gen/testdata/simple_resource/test.golden.go @@ -1,4 +1,4 @@ -// Code generated from testdata/simple-resource.cdc. DO NOT EDIT. +// Code generated from testdata/simple_resource/test.cdc. DO NOT EDIT. /* * Cadence - The resource-oriented smart contract programming language * @@ -17,15 +17,17 @@ * limitations under the License. */ -package sema +package simple_resource + +import "github.com/onflow/cadence/runtime/sema" const TestTypeName = "Test" -var TestType = &SimpleType{ +var TestType = &sema.SimpleType{ Name: TestTypeName, QualifiedName: TestTypeName, TypeID: TestTypeName, - tag: TestTypeTag, + TypeTag: TestTypeTag, IsResource: true, Storable: false, Equatable: false, diff --git a/runtime/sema/gen/testdata/simple_struct/helper.go b/runtime/sema/gen/testdata/simple_struct/helper.go new file mode 100644 index 0000000000..b9cf6dd4da --- /dev/null +++ b/runtime/sema/gen/testdata/simple_struct/helper.go @@ -0,0 +1,23 @@ +/* + * Cadence - The resource-oriented smart contract programming language + * + * Copyright Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package simple_struct + +import "github.com/onflow/cadence/runtime/sema" + +var TestTypeTag sema.TypeTag diff --git a/runtime/sema/gen/testdata/simple-struct.cdc b/runtime/sema/gen/testdata/simple_struct/test.cdc similarity index 100% rename from runtime/sema/gen/testdata/simple-struct.cdc rename to runtime/sema/gen/testdata/simple_struct/test.cdc diff --git a/runtime/sema/gen/testdata/simple-struct.golden.go b/runtime/sema/gen/testdata/simple_struct/test.golden.go similarity index 82% rename from runtime/sema/gen/testdata/simple-struct.golden.go rename to runtime/sema/gen/testdata/simple_struct/test.golden.go index 0429d008f3..4606268f1d 100644 --- a/runtime/sema/gen/testdata/simple-struct.golden.go +++ b/runtime/sema/gen/testdata/simple_struct/test.golden.go @@ -1,4 +1,4 @@ -// Code generated from testdata/simple-struct.cdc. DO NOT EDIT. +// Code generated from testdata/simple_struct/test.cdc. DO NOT EDIT. /* * Cadence - The resource-oriented smart contract programming language * @@ -17,15 +17,17 @@ * limitations under the License. */ -package sema +package simple_struct + +import "github.com/onflow/cadence/runtime/sema" const TestTypeName = "Test" -var TestType = &SimpleType{ +var TestType = &sema.SimpleType{ Name: TestTypeName, QualifiedName: TestTypeName, TypeID: TestTypeName, - tag: TestTypeTag, + TypeTag: TestTypeTag, IsResource: false, Storable: false, Equatable: false, diff --git a/runtime/sema/gen/testdata/storable/helper.go b/runtime/sema/gen/testdata/storable/helper.go new file mode 100644 index 0000000000..cd8334e96c --- /dev/null +++ b/runtime/sema/gen/testdata/storable/helper.go @@ -0,0 +1,23 @@ +/* + * Cadence - The resource-oriented smart contract programming language + * + * Copyright Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package storable + +import "github.com/onflow/cadence/runtime/sema" + +var TestTypeTag sema.TypeTag diff --git a/runtime/sema/gen/testdata/storable.cdc b/runtime/sema/gen/testdata/storable/test.cdc similarity index 100% rename from runtime/sema/gen/testdata/storable.cdc rename to runtime/sema/gen/testdata/storable/test.cdc diff --git a/runtime/sema/gen/testdata/storable.golden.go b/runtime/sema/gen/testdata/storable/test.golden.go similarity index 83% rename from runtime/sema/gen/testdata/storable.golden.go rename to runtime/sema/gen/testdata/storable/test.golden.go index c9c5526991..5a01604df9 100644 --- a/runtime/sema/gen/testdata/storable.golden.go +++ b/runtime/sema/gen/testdata/storable/test.golden.go @@ -1,4 +1,4 @@ -// Code generated from testdata/storable.cdc. DO NOT EDIT. +// Code generated from testdata/storable/test.cdc. DO NOT EDIT. /* * Cadence - The resource-oriented smart contract programming language * @@ -17,15 +17,17 @@ * limitations under the License. */ -package sema +package storable + +import "github.com/onflow/cadence/runtime/sema" const TestTypeName = "Test" -var TestType = &SimpleType{ +var TestType = &sema.SimpleType{ Name: TestTypeName, QualifiedName: TestTypeName, TypeID: TestTypeName, - tag: TestTypeTag, + TypeTag: TestTypeTag, IsResource: false, Storable: true, Equatable: false, diff --git a/runtime/sema/invalid_type.go b/runtime/sema/invalid_type.go index d0ce0787ec..409d50f5ab 100644 --- a/runtime/sema/invalid_type.go +++ b/runtime/sema/invalid_type.go @@ -25,7 +25,7 @@ var InvalidType = &SimpleType{ Name: "<>", QualifiedName: "<>", TypeID: "<>", - tag: InvalidTypeTag, + TypeTag: InvalidTypeTag, IsResource: false, Storable: false, Equatable: false, diff --git a/runtime/sema/meta_type.go b/runtime/sema/meta_type.go index 59d6c4281b..6ee455c1ab 100644 --- a/runtime/sema/meta_type.go +++ b/runtime/sema/meta_type.go @@ -37,7 +37,7 @@ var MetaType = &SimpleType{ Name: MetaTypeName, QualifiedName: MetaTypeName, TypeID: MetaTypeName, - tag: MetaTypeTag, + TypeTag: MetaTypeTag, IsResource: false, Storable: true, Equatable: true, diff --git a/runtime/sema/never_type.go b/runtime/sema/never_type.go index 1722259379..0d3fe642f5 100644 --- a/runtime/sema/never_type.go +++ b/runtime/sema/never_type.go @@ -23,7 +23,7 @@ var NeverType = &SimpleType{ Name: "Never", QualifiedName: "Never", TypeID: "Never", - tag: NeverTypeTag, + TypeTag: NeverTypeTag, IsResource: false, Storable: false, Equatable: false, diff --git a/runtime/sema/path_type.go b/runtime/sema/path_type.go index 41b19dd6f1..fa443cd17f 100644 --- a/runtime/sema/path_type.go +++ b/runtime/sema/path_type.go @@ -23,7 +23,7 @@ var PathType = &SimpleType{ Name: "Path", QualifiedName: "Path", TypeID: "Path", - tag: PathTypeTag, + TypeTag: PathTypeTag, IsResource: false, Storable: true, Equatable: true, @@ -43,7 +43,7 @@ var StoragePathType = &SimpleType{ Name: "StoragePath", QualifiedName: "StoragePath", TypeID: "StoragePath", - tag: StoragePathTypeTag, + TypeTag: StoragePathTypeTag, IsResource: false, Storable: true, Equatable: true, @@ -59,7 +59,7 @@ var CapabilityPathType = &SimpleType{ Name: "CapabilityPath", QualifiedName: "CapabilityPath", TypeID: "CapabilityPath", - tag: CapabilityPathTypeTag, + TypeTag: CapabilityPathTypeTag, IsResource: false, Storable: true, Equatable: true, @@ -79,7 +79,7 @@ var PublicPathType = &SimpleType{ Name: "PublicPath", QualifiedName: "PublicPath", TypeID: "PublicPath", - tag: PublicPathTypeTag, + TypeTag: PublicPathTypeTag, IsResource: false, Storable: true, Equatable: true, @@ -95,7 +95,7 @@ var PrivatePathType = &SimpleType{ Name: "PrivatePath", QualifiedName: "PrivatePath", TypeID: "PrivatePath", - tag: PrivatePathTypeTag, + TypeTag: PrivatePathTypeTag, IsResource: false, Storable: true, Equatable: true, diff --git a/runtime/sema/simple_type.go b/runtime/sema/simple_type.go index f137fdf61a..7e6affd690 100644 --- a/runtime/sema/simple_type.go +++ b/runtime/sema/simple_type.go @@ -42,7 +42,7 @@ type SimpleType struct { QualifiedName string TypeID TypeID Name string - tag TypeTag + TypeTag TypeTag memberResolversOnce sync.Once Importable bool Exportable bool @@ -60,7 +60,7 @@ var _ ContainerType = &SimpleType{} func (*SimpleType) IsType() {} func (t *SimpleType) Tag() TypeTag { - return t.tag + return t.TypeTag } func (t *SimpleType) String() string { diff --git a/runtime/sema/storage_capability_controller.gen.go b/runtime/sema/storage_capability_controller.gen.go index c74ed0974a..9ef52376db 100644 --- a/runtime/sema/storage_capability_controller.gen.go +++ b/runtime/sema/storage_capability_controller.gen.go @@ -134,7 +134,7 @@ var StorageCapabilityControllerType = &SimpleType{ Name: StorageCapabilityControllerTypeName, QualifiedName: StorageCapabilityControllerTypeName, TypeID: StorageCapabilityControllerTypeName, - tag: StorageCapabilityControllerTypeTag, + TypeTag: StorageCapabilityControllerTypeTag, IsResource: false, Storable: false, Equatable: false, diff --git a/runtime/sema/string_type.go b/runtime/sema/string_type.go index b4fa762599..74b9baaccf 100644 --- a/runtime/sema/string_type.go +++ b/runtime/sema/string_type.go @@ -42,12 +42,17 @@ const StringTypeJoinFunctionDocString = ` Returns a string after joining the array of strings with the provided separator. ` +const StringTypeSplitFunctionName = "split" +const StringTypeSplitFunctionDocString = ` +Returns a variable-sized array of strings after splitting the string on the delimiter. +` + // StringType represents the string type var StringType = &SimpleType{ Name: "String", QualifiedName: "String", TypeID: "String", - tag: StringTypeTag, + TypeTag: StringTypeTag, IsResource: false, Storable: true, Equatable: true, @@ -105,6 +110,12 @@ func init() { StringTypeToLowerFunctionType, stringTypeToLowerFunctionDocString, ), + NewUnmeteredPublicFunctionMember( + t, + StringTypeSplitFunctionName, + StringTypeSplitFunctionType, + StringTypeSplitFunctionDocString, + ), }) } } @@ -335,3 +346,18 @@ var StringTypeJoinFunctionType = NewSimpleFunctionType( }, StringTypeAnnotation, ) + +var StringTypeSplitFunctionType = NewSimpleFunctionType( + FunctionPurityView, + []Parameter{ + { + Identifier: "separator", + TypeAnnotation: StringTypeAnnotation, + }, + }, + NewTypeAnnotation( + &VariableSizedType{ + Type: StringType, + }, + ), +) diff --git a/runtime/sema/type.go b/runtime/sema/type.go index f866b7b45b..cf7be4bf8e 100644 --- a/runtime/sema/type.go +++ b/runtime/sema/type.go @@ -4735,7 +4735,11 @@ func (t *CompositeType) GetMembers() map[string]MemberResolver { } func (t *CompositeType) initializeMemberResolvers() { - t.memberResolversOnce.Do(func() { + t.memberResolversOnce.Do(t.initializerMemberResolversFunc()) +} + +func (t *CompositeType) initializerMemberResolversFunc() func() { + return func() { memberResolvers := MembersMapAsResolvers(t.Members) // Check conformances. @@ -4770,7 +4774,13 @@ func (t *CompositeType) initializeMemberResolvers() { } t.memberResolvers = withBuiltinMembers(t, memberResolvers) - }) + } +} + +func (t *CompositeType) ResolveMembers() { + if t.Members.Len() != len(t.GetMembers()) { + t.initializerMemberResolversFunc()() + } } func (t *CompositeType) FieldPosition(name string, declaration ast.CompositeLikeDeclaration) ast.Position { @@ -4924,6 +4934,48 @@ func NewFunctionMember( } } +func NewUnmeteredConstructorMember( + containerType Type, + access Access, + identifier string, + functionType *FunctionType, + docString string, +) *Member { + return NewConstructorMember( + nil, + containerType, + access, + identifier, + functionType, + docString, + ) +} + +func NewConstructorMember( + memoryGauge common.MemoryGauge, + containerType Type, + access Access, + identifier string, + functionType *FunctionType, + docString string, +) *Member { + + return &Member{ + ContainerType: containerType, + Access: access, + Identifier: ast.NewIdentifier( + memoryGauge, + identifier, + ast.EmptyPosition, + ), + DeclarationKind: common.DeclarationKindInitializer, + VariableKind: ast.VariableKindConstant, + TypeAnnotation: NewTypeAnnotation(functionType), + ArgumentLabels: functionType.ArgumentLabels(), + DocString: docString, + } +} + func NewUnmeteredPublicConstantFieldMember( containerType Type, identifier string, diff --git a/runtime/sema/void_type.go b/runtime/sema/void_type.go index a35ab56d9d..4ebe233b58 100644 --- a/runtime/sema/void_type.go +++ b/runtime/sema/void_type.go @@ -23,7 +23,7 @@ var VoidType = &SimpleType{ Name: "Void", QualifiedName: "Void", TypeID: "Void", - tag: VoidTypeTag, + TypeTag: VoidTypeTag, IsResource: false, Storable: false, Equatable: true, diff --git a/runtime/stdlib/account.go b/runtime/stdlib/account.go index f830890476..8c26d7448d 100644 --- a/runtime/stdlib/account.go +++ b/runtime/stdlib/account.go @@ -1349,7 +1349,11 @@ type AccountContractAdditionHandler interface { ) (*interpreter.Program, error) // UpdateAccountContractCode updates the code associated with an account contract. UpdateAccountContractCode(location common.AddressLocation, code []byte) error - RecordContractUpdate(location common.AddressLocation, value *interpreter.CompositeValue) + RecordContractUpdate( + location common.AddressLocation, + value *interpreter.CompositeValue, + ) + ContractUpdateRecorded(location common.AddressLocation) bool InterpretContract( location common.AddressLocation, program *interpreter.Program, @@ -1443,9 +1447,10 @@ func changeAccountContracts( } else { // We are adding a new contract. - // Ensure that no contract/contract interface with the given name exists already + // Ensure that no contract/contract interface with the given name exists already, + // and no contract deploy or update was recorded before - if len(existingCode) > 0 { + if len(existingCode) > 0 || handler.ContractUpdateRecorded(location) { panic(errors.NewDefaultUserError( "cannot overwrite existing contract with name %q in account %s", contractName, @@ -2653,33 +2658,32 @@ func getCapabilityController( capabilityID := controller.CapabilityID controller.GetCapability = - newCapabilityControllerGetCapabilityFunction(inter, address, controller) + newCapabilityControllerGetCapabilityFunction(address, controller) controller.GetTag = - newCapabilityControllerGetTagFunction(inter, address, capabilityID) + newCapabilityControllerGetTagFunction(address, capabilityID) controller.SetTag = - newCapabilityControllerSetTagFunction(inter, address, capabilityID) + newCapabilityControllerSetTagFunction(address, capabilityID) - controller.TargetFunction = - newStorageCapabilityControllerTargetFunction(inter, controller) - controller.RetargetFunction = - newStorageCapabilityControllerRetargetFunction(inter, address, controller) - controller.DeleteFunction = - newStorageCapabilityControllerDeleteFunction(inter, address, controller) + controller.Delete = + newStorageCapabilityControllerDeleteFunction(address, controller) + + controller.SetTarget = + newStorageCapabilityControllerSetTargetFunction(address, controller) case *interpreter.AccountCapabilityControllerValue: capabilityID := controller.CapabilityID controller.GetCapability = - newCapabilityControllerGetCapabilityFunction(inter, address, controller) + newCapabilityControllerGetCapabilityFunction(address, controller) controller.GetTag = - newCapabilityControllerGetTagFunction(inter, address, capabilityID) + newCapabilityControllerGetTagFunction(address, capabilityID) controller.SetTag = - newCapabilityControllerSetTagFunction(inter, address, capabilityID) + newCapabilityControllerSetTagFunction(address, capabilityID) - controller.DeleteFunction = - newAccountCapabilityControllerDeleteFunction(inter, address, controller) + controller.Delete = + newAccountCapabilityControllerDeleteFunction(address, controller) } return controller @@ -2709,94 +2713,59 @@ func getStorageCapabilityControllerReference( ) } -func newStorageCapabilityControllerTargetFunction( - inter *interpreter.Interpreter, - controller *interpreter.StorageCapabilityControllerValue, -) interpreter.FunctionValue { - return interpreter.NewHostFunctionValue( - inter, - sema.StorageCapabilityControllerTypeTargetFunctionType, - func(invocation interpreter.Invocation) interpreter.Value { - return controller.TargetPath - }, - ) -} - -func newStorageCapabilityControllerRetargetFunction( - inter *interpreter.Interpreter, +func newStorageCapabilityControllerSetTargetFunction( address common.Address, controller *interpreter.StorageCapabilityControllerValue, -) interpreter.FunctionValue { - return interpreter.NewHostFunctionValue( - inter, - sema.StorageCapabilityControllerTypeTargetFunctionType, - func(invocation interpreter.Invocation) interpreter.Value { - locationRange := invocation.LocationRange - - // Get path argument - - newTargetPathValue, ok := invocation.Arguments[0].(interpreter.PathValue) - if !ok || newTargetPathValue.Domain != common.PathDomainStorage { - panic(errors.NewUnreachableError()) - } - - oldTargetPathValue := controller.TargetPath - - capabilityID := controller.CapabilityID - unrecordStorageCapabilityController( - inter, - locationRange, - address, - oldTargetPathValue, - capabilityID, - ) - recordStorageCapabilityController( - inter, - locationRange, - address, - newTargetPathValue, - capabilityID, - ) - - controller.TargetPath = newTargetPathValue +) func(*interpreter.Interpreter, interpreter.LocationRange, interpreter.PathValue) { + return func( + inter *interpreter.Interpreter, + locationRange interpreter.LocationRange, + newTargetPathValue interpreter.PathValue, + ) { + oldTargetPathValue := controller.TargetPath + capabilityID := controller.CapabilityID - return interpreter.Void - }, - ) + unrecordStorageCapabilityController( + inter, + locationRange, + address, + oldTargetPathValue, + capabilityID, + ) + recordStorageCapabilityController( + inter, + locationRange, + address, + newTargetPathValue, + capabilityID, + ) + } } func newStorageCapabilityControllerDeleteFunction( - inter *interpreter.Interpreter, address common.Address, controller *interpreter.StorageCapabilityControllerValue, -) interpreter.FunctionValue { - return interpreter.NewHostFunctionValue( - inter, - sema.StorageCapabilityControllerTypeTargetFunctionType, - func(invocation interpreter.Invocation) interpreter.Value { - inter := invocation.Interpreter - locationRange := invocation.LocationRange - - capabilityID := controller.CapabilityID - - unrecordStorageCapabilityController( - inter, - locationRange, - address, - controller.TargetPath, - capabilityID, - ) - removeCapabilityController( - inter, - address, - capabilityID, - ) - - controller.SetDeleted(inter) +) func(*interpreter.Interpreter, interpreter.LocationRange) { + return func( + inter *interpreter.Interpreter, + locationRange interpreter.LocationRange, + ) { + targetPathValue := controller.TargetPath + capabilityID := controller.CapabilityID - return interpreter.Void - }, - ) + unrecordStorageCapabilityController( + inter, + locationRange, + address, + targetPathValue, + capabilityID, + ) + removeCapabilityController( + inter, + address, + capabilityID, + ) + } } var capabilityIDSetStaticType = &interpreter.DictionaryStaticType{ @@ -3745,37 +3714,24 @@ func newAccountAccountCapabilitiesForEachControllerFunction( } func newAccountCapabilityControllerDeleteFunction( - inter *interpreter.Interpreter, address common.Address, controller *interpreter.AccountCapabilityControllerValue, -) interpreter.FunctionValue { - return interpreter.NewHostFunctionValue( - inter, - sema.StorageCapabilityControllerTypeTargetFunctionType, - func(invocation interpreter.Invocation) interpreter.Value { - - inter := invocation.Interpreter - locationRange := invocation.LocationRange - - capabilityID := controller.CapabilityID - - unrecordAccountCapabilityController( - inter, - locationRange, - address, - capabilityID, - ) - removeCapabilityController( - inter, - address, - capabilityID, - ) - - controller.SetDeleted(inter) +) func(*interpreter.Interpreter, interpreter.LocationRange) { + return func(inter *interpreter.Interpreter, locationRange interpreter.LocationRange) { + capabilityID := controller.CapabilityID - return interpreter.Void - }, - ) + unrecordAccountCapabilityController( + inter, + locationRange, + address, + capabilityID, + ) + removeCapabilityController( + inter, + address, + capabilityID, + ) + } } // CapabilityControllerTagStorageDomain is the storage domain which stores @@ -3806,16 +3762,15 @@ func getCapabilityControllerTag( } func newCapabilityControllerGetCapabilityFunction( - inter *interpreter.Interpreter, address common.Address, controller interpreter.CapabilityControllerValue, -) func() *interpreter.CapabilityValue { +) func(inter *interpreter.Interpreter) *interpreter.CapabilityValue { addressValue := interpreter.AddressValue(address) capabilityID := controller.ControllerCapabilityID() borrowType := controller.CapabilityControllerBorrowType() - return func() *interpreter.CapabilityValue { + return func(inter *interpreter.Interpreter) *interpreter.CapabilityValue { return interpreter.NewCapabilityValue( inter, capabilityID, @@ -3826,12 +3781,11 @@ func newCapabilityControllerGetCapabilityFunction( } func newCapabilityControllerGetTagFunction( - inter *interpreter.Interpreter, address common.Address, capabilityIDValue interpreter.UInt64Value, -) func() *interpreter.StringValue { +) func(*interpreter.Interpreter) *interpreter.StringValue { - return func() *interpreter.StringValue { + return func(inter *interpreter.Interpreter) *interpreter.StringValue { return getCapabilityControllerTag( inter, address, @@ -3861,11 +3815,10 @@ func setCapabilityControllerTag( } func newCapabilityControllerSetTagFunction( - inter *interpreter.Interpreter, address common.Address, capabilityIDValue interpreter.UInt64Value, -) func(tagValue *interpreter.StringValue) { - return func(tagValue *interpreter.StringValue) { +) func(*interpreter.Interpreter, *interpreter.StringValue) { + return func(inter *interpreter.Interpreter, tagValue *interpreter.StringValue) { setCapabilityControllerTag( inter, address, diff --git a/runtime/stdlib/bls.gen.go b/runtime/stdlib/bls.gen.go index e88a5939fa..cde94eb341 100644 --- a/runtime/stdlib/bls.gen.go +++ b/runtime/stdlib/bls.gen.go @@ -35,7 +35,7 @@ var BLSTypeAggregateSignaturesFunctionType = &sema.FunctionType{ Identifier: "signatures", TypeAnnotation: sema.NewTypeAnnotation(&sema.VariableSizedType{ Type: &sema.VariableSizedType{ - Type: UInt8Type, + Type: sema.UInt8Type, }, }), }, @@ -43,7 +43,7 @@ var BLSTypeAggregateSignaturesFunctionType = &sema.FunctionType{ ReturnTypeAnnotation: sema.NewTypeAnnotation( &sema.OptionalType{ Type: &sema.VariableSizedType{ - Type: UInt8Type, + Type: sema.UInt8Type, }, }, ), @@ -69,13 +69,13 @@ var BLSTypeAggregatePublicKeysFunctionType = &sema.FunctionType{ Label: sema.ArgumentLabelNotRequired, Identifier: "keys", TypeAnnotation: sema.NewTypeAnnotation(&sema.VariableSizedType{ - Type: PublicKeyType, + Type: sema.PublicKeyType, }), }, }, ReturnTypeAnnotation: sema.NewTypeAnnotation( &sema.OptionalType{ - Type: PublicKeyType, + Type: sema.PublicKeyType, }, ), } diff --git a/runtime/stdlib/builtin.go b/runtime/stdlib/builtin.go index d462a5f83d..d292eb1bef 100644 --- a/runtime/stdlib/builtin.go +++ b/runtime/stdlib/builtin.go @@ -18,10 +18,6 @@ package stdlib -import "github.com/onflow/cadence/runtime/sema" - -var UInt8Type = sema.UInt8Type - type StandardLibraryHandler interface { Logger UnsafeRandomGenerator diff --git a/runtime/stdlib/contracts/test.cdc b/runtime/stdlib/contracts/test.cdc index 8a6634e082..70a484d54f 100644 --- a/runtime/stdlib/contracts/test.cdc +++ b/runtime/stdlib/contracts/test.cdc @@ -3,177 +3,170 @@ access(all) contract Test { - /// Blockchain emulates a real network. + /// backend emulates a real network. /// - access(all) - struct Blockchain { + access(self) + let backend: {BlockchainBackend} - access(all) - let backend: {BlockchainBackend} + init(backend: {BlockchainBackend}) { + self.backend = backend + } - init(backend: {BlockchainBackend}) { - self.backend = backend - } + /// Executes a script and returns the script return value and the status. + /// `returnValue` field of the result will be `nil` if the script failed. + /// + access(all) + fun executeScript(_ script: String, _ arguments: [AnyStruct]): ScriptResult { + return self.backend.executeScript(script, arguments) + } - /// Executes a script and returns the script return value and the status. - /// `returnValue` field of the result will be `nil` if the script failed. - /// - access(all) - fun executeScript(_ script: String, _ arguments: [AnyStruct]): ScriptResult { - return self.backend.executeScript(script, arguments) - } + /// Creates a signer account by submitting an account creation transaction. + /// The transaction is paid by the service account. + /// The returned account can be used to sign and authorize transactions. + /// + access(all) + fun createAccount(): TestAccount { + return self.backend.createAccount() + } - /// Creates a signer account by submitting an account creation transaction. - /// The transaction is paid by the service account. - /// The returned account can be used to sign and authorize transactions. - /// - access(all) - fun createAccount(): TestAccount { - return self.backend.createAccount() - } + /// Returns the account for the given address. + /// + access(all) + fun getAccount(_ address: Address): TestAccount { + return self.backend.getAccount(address) + } - /// Add a transaction to the current block. - /// - access(all) - fun addTransaction(_ tx: Transaction) { - self.backend.addTransaction(tx) - } + /// Add a transaction to the current block. + /// + access(all) + fun addTransaction(_ tx: Transaction) { + self.backend.addTransaction(tx) + } - /// Executes the next transaction in the block, if any. - /// Returns the result of the transaction, or nil if no transaction was scheduled. - /// - access(all) - fun executeNextTransaction(): TransactionResult? { - return self.backend.executeNextTransaction() - } + /// Executes the next transaction in the block, if any. + /// Returns the result of the transaction, or nil if no transaction was scheduled. + /// + access(all) + fun executeNextTransaction(): TransactionResult? { + return self.backend.executeNextTransaction() + } - /// Commit the current block. - /// Committing will fail if there are un-executed transactions in the block. - /// - access(all) - fun commitBlock() { - self.backend.commitBlock() - } + /// Commit the current block. + /// Committing will fail if there are un-executed transactions in the block. + /// + access(all) + fun commitBlock() { + self.backend.commitBlock() + } - /// Executes a given transaction and commit the current block. - /// - access(all) - fun executeTransaction(_ tx: Transaction): TransactionResult { + /// Executes a given transaction and commit the current block. + /// + access(all) + fun executeTransaction(_ tx: Transaction): TransactionResult { + self.addTransaction(tx) + let txResult = self.executeNextTransaction()! + self.commitBlock() + return txResult + } + + /// Executes a given set of transactions and commit the current block. + /// + access(all) + fun executeTransactions(_ transactions: [Transaction]): [TransactionResult] { + for tx in transactions { self.addTransaction(tx) - let txResult = self.executeNextTransaction()! - self.commitBlock() - return txResult } - /// Executes a given set of transactions and commit the current block. - /// - access(all) - fun executeTransactions(_ transactions: [Transaction]): [TransactionResult] { - for tx in transactions { - self.addTransaction(tx) - } - - var results: [TransactionResult] = [] - for tx in transactions { - let txResult = self.executeNextTransaction()! - results.append(txResult) - } - - self.commitBlock() - return results + var results: [TransactionResult] = [] + for tx in transactions { + let txResult = self.executeNextTransaction()! + results.append(txResult) } - /// Deploys a given contract, and initilizes it with the arguments. - /// - access(all) - fun deployContract( - name: String, - code: String, - account: TestAccount, - arguments: [AnyStruct] - ): Error? { - return self.backend.deployContract( - name: name, - code: code, - account: account, - arguments: arguments - ) - } + self.commitBlock() + return results + } - /// Set the configuration to be used by the blockchain. - /// Overrides any existing configuration. - /// - access(all) - fun useConfiguration(_ configuration: Configuration) { - self.backend.useConfiguration(configuration) - } + /// Deploys a given contract, and initilizes it with the arguments. + /// + access(all) + fun deployContract( + name: String, + path: String, + arguments: [AnyStruct] + ): Error? { + return self.backend.deployContract( + name: name, + path: path, + arguments: arguments + ) + } - /// Returns all the logs from the blockchain, up to the calling point. - /// - access(all) - fun logs(): [String] { - return self.backend.logs() - } + /// Returns all the logs from the blockchain, up to the calling point. + /// + access(all) + fun logs(): [String] { + return self.backend.logs() + } - /// Returns the service account of the blockchain. Can be used to sign - /// transactions with this account. - /// - access(all) - fun serviceAccount(): TestAccount { - return self.backend.serviceAccount() - } + /// Returns the service account of the blockchain. Can be used to sign + /// transactions with this account. + /// + access(all) + fun serviceAccount(): TestAccount { + return self.backend.serviceAccount() + } - /// Returns all events emitted from the blockchain. - /// - access(all) - fun events(): [AnyStruct] { - return self.backend.events(nil) - } + /// Returns all events emitted from the blockchain. + /// + access(all) + fun events(): [AnyStruct] { + return self.backend.events(nil) + } - /// Returns all events emitted from the blockchain, - /// filtered by type. - /// - access(all) - fun eventsOfType(_ type: Type): [AnyStruct] { - return self.backend.events(type) - } + /// Returns all events emitted from the blockchain, + /// filtered by type. + /// + access(all) + fun eventsOfType(_ type: Type): [AnyStruct] { + return self.backend.events(type) + } - /// Resets the state of the blockchain to the given height. - /// - access(all) - fun reset(to height: UInt64) { - self.backend.reset(to: height) - } + /// Resets the state of the blockchain to the given height. + /// + access(all) + fun reset(to height: UInt64) { + self.backend.reset(to: height) + } - /// Moves the time of the blockchain by the given delta, - /// which should be passed in the form of seconds. - /// - access(all) - fun moveTime(by delta: Fix64) { - self.backend.moveTime(by: delta) - } + /// Moves the time of the blockchain by the given delta, + /// which should be passed in the form of seconds. + /// + access(all) + fun moveTime(by delta: Fix64) { + self.backend.moveTime(by: delta) + } - /// Creates a snapshot of the blockchain, at the - /// current ledger state, with the given name. - /// - access(all) - fun createSnapshot(name: String) { - let err = self.backend.createSnapshot(name: name) - if err != nil { - panic(err!.message) - } + /// Creates a snapshot of the blockchain, at the + /// current ledger state, with the given name. + /// + access(all) + fun createSnapshot(name: String) { + let err = self.backend.createSnapshot(name: name) + if err != nil { + panic(err!.message) } + } - /// Loads a snapshot of the blockchain, with the - /// given name, and updates the current ledger - /// state. - /// - access(all) - fun loadSnapshot(name: String) { - let err = self.backend.loadSnapshot(name: name) - if err != nil { - panic(err!.message) - } + /// Loads a snapshot of the blockchain, with the + /// given name, and updates the current ledger + /// state. + /// + access(all) + fun loadSnapshot(name: String) { + let err = self.backend.loadSnapshot(name: name) + if err != nil { + panic(err!.message) } } @@ -183,7 +176,6 @@ contract Test { access(all) let test: fun(AnyStruct): Bool - access(all) init(test: fun(AnyStruct): Bool) { self.test = test } @@ -275,6 +267,7 @@ contract Test { // access(all) struct Error { + access(all) let message: String @@ -300,20 +293,6 @@ contract Test { } } - /// Configuration to be used by the blockchain. - /// Can be used to set the address mappings. - /// - access(all) - struct Configuration { - - access(all) - let addresses: {String: Address} - - init(addresses: {String: Address}) { - self.addresses = addresses - } - } - /// Transaction that can be submitted and executed on the blockchain. /// access(all) @@ -357,6 +336,11 @@ contract Test { access(all) fun createAccount(): TestAccount + /// Returns the account for the given address. + /// + access(all) + fun getAccount(_ address: Address): TestAccount + /// Add a transaction to the current block. /// access(all) @@ -379,17 +363,10 @@ contract Test { access(all) fun deployContract( name: String, - code: String, - account: TestAccount, + path: String, arguments: [AnyStruct] ): Error? - /// Set the configuration to be used by the blockchain. - /// Overrides any existing configuration. - /// - access(all) - fun useConfiguration(_ configuration: Configuration) - /// Returns all the logs from the blockchain, up to the calling point. /// access(all) diff --git a/runtime/stdlib/flow.go b/runtime/stdlib/flow.go index f34cfd633a..47451caf56 100644 --- a/runtime/stdlib/flow.go +++ b/runtime/stdlib/flow.go @@ -193,7 +193,7 @@ var AccountEventCodeHashParameter = sema.Parameter{ var AccountEventPublicKeyParameterAsCompositeType = sema.Parameter{ Identifier: "publicKey", TypeAnnotation: sema.NewTypeAnnotation( - PublicKeyType, + sema.PublicKeyType, ), } diff --git a/runtime/stdlib/publickey.go b/runtime/stdlib/publickey.go index 5b02f4250d..ef27bebc3a 100644 --- a/runtime/stdlib/publickey.go +++ b/runtime/stdlib/publickey.go @@ -25,8 +25,6 @@ import ( "github.com/onflow/cadence/runtime/sema" ) -var PublicKeyType = sema.PublicKeyType - const publicKeyConstructorFunctionDocString = ` Constructs a new public key ` @@ -260,7 +258,7 @@ func newPublicKeyVerifySignatureFunction( inter.ExpectType( publicKeyValue, - PublicKeyType, + sema.PublicKeyType, locationRange, ) @@ -330,7 +328,7 @@ func newPublicKeyVerifyPoPFunction( inter.ExpectType( publicKeyValue, - PublicKeyType, + sema.PublicKeyType, locationRange, ) diff --git a/runtime/stdlib/rlp.gen.go b/runtime/stdlib/rlp.gen.go index 44aac52a78..1fdf0f7895 100644 --- a/runtime/stdlib/rlp.gen.go +++ b/runtime/stdlib/rlp.gen.go @@ -34,13 +34,13 @@ var RLPTypeDecodeStringFunctionType = &sema.FunctionType{ Label: sema.ArgumentLabelNotRequired, Identifier: "input", TypeAnnotation: sema.NewTypeAnnotation(&sema.VariableSizedType{ - Type: UInt8Type, + Type: sema.UInt8Type, }), }, }, ReturnTypeAnnotation: sema.NewTypeAnnotation( &sema.VariableSizedType{ - Type: UInt8Type, + Type: sema.UInt8Type, }, ), } @@ -61,14 +61,14 @@ var RLPTypeDecodeListFunctionType = &sema.FunctionType{ Label: sema.ArgumentLabelNotRequired, Identifier: "input", TypeAnnotation: sema.NewTypeAnnotation(&sema.VariableSizedType{ - Type: UInt8Type, + Type: sema.UInt8Type, }), }, }, ReturnTypeAnnotation: sema.NewTypeAnnotation( &sema.VariableSizedType{ Type: &sema.VariableSizedType{ - Type: UInt8Type, + Type: sema.UInt8Type, }, }, ), diff --git a/runtime/stdlib/test-framework.go b/runtime/stdlib/test-framework.go index 3e8d0523c2..6496ee98fb 100644 --- a/runtime/stdlib/test-framework.go +++ b/runtime/stdlib/test-framework.go @@ -30,7 +30,7 @@ import ( // This is used as a way to inject test provider dependencies dynamically. type TestFramework interface { - NewEmulatorBackend() Blockchain + EmulatorBackend() Blockchain ReadFile(string) (string, error) } @@ -43,6 +43,8 @@ type Blockchain interface { CreateAccount() (*Account, error) + GetAccount(interpreter.AddressValue) (*Account, error) + AddTransaction( inter *interpreter.Interpreter, code string, @@ -58,13 +60,10 @@ type Blockchain interface { DeployContract( inter *interpreter.Interpreter, name string, - code string, - account *Account, + path string, arguments []interpreter.Value, ) error - UseConfiguration(configuration *Configuration) - StandardLibraryHandler() StandardLibraryHandler Logs() []string @@ -98,7 +97,3 @@ type Account struct { PublicKey *PublicKey Address common.Address } - -type Configuration struct { - Addresses map[string]common.Address -} diff --git a/runtime/stdlib/test.go b/runtime/stdlib/test.go index 47a565cb8f..de914c21a9 100644 --- a/runtime/stdlib/test.go +++ b/runtime/stdlib/test.go @@ -48,8 +48,6 @@ const accountAddressFieldName = "address" const matcherTestFieldName = "test" -const addressesFieldName = "addresses" - const TestContractLocation = common.IdentifierLocation(testContractTypeName) var testOnce sync.Once diff --git a/runtime/stdlib/test_contract.go b/runtime/stdlib/test_contract.go index 488f1f24f4..2467f48331 100644 --- a/runtime/stdlib/test_contract.go +++ b/runtime/stdlib/test_contract.go @@ -32,20 +32,19 @@ import ( ) type TestContractType struct { - Checker *sema.Checker - CompositeType *sema.CompositeType - InitializerTypes []sema.Type - emulatorBackendType *testEmulatorBackendType - newEmulatorBlockchainFunctionType *sema.FunctionType - expectFunction interpreter.FunctionValue - newMatcherFunction interpreter.FunctionValue - haveElementCountFunction interpreter.FunctionValue - beEmptyFunction interpreter.FunctionValue - equalFunction interpreter.FunctionValue - beGreaterThanFunction interpreter.FunctionValue - containFunction interpreter.FunctionValue - beLessThanFunction interpreter.FunctionValue - expectFailureFunction interpreter.FunctionValue + Checker *sema.Checker + CompositeType *sema.CompositeType + InitializerTypes []sema.Type + emulatorBackendType *testEmulatorBackendType + expectFunction interpreter.FunctionValue + newMatcherFunction interpreter.FunctionValue + haveElementCountFunction interpreter.FunctionValue + beEmptyFunction interpreter.FunctionValue + equalFunction interpreter.FunctionValue + beGreaterThanFunction interpreter.FunctionValue + containFunction interpreter.FunctionValue + beLessThanFunction interpreter.FunctionValue + expectFailureFunction interpreter.FunctionValue } // 'Test.assert' function @@ -366,65 +365,6 @@ func newTestTypeReadFileFunction(testFramework TestFramework) *interpreter.HostF ) } -// 'Test.newEmulatorBlockchain' function - -const testTypeNewEmulatorBlockchainFunctionDocString = ` -Creates a blockchain which is backed by a new emulator instance. -` - -const testTypeNewEmulatorBlockchainFunctionName = "newEmulatorBlockchain" - -const testBlockchainTypeName = "Blockchain" - -func newTestTypeNewEmulatorBlockchainFunctionType(blockchainType *sema.CompositeType) *sema.FunctionType { - return &sema.FunctionType{ - ReturnTypeAnnotation: sema.NewTypeAnnotation( - blockchainType, - ), - } -} - -func (t *TestContractType) newNewEmulatorBlockchainFunction( - testFramework TestFramework, -) *interpreter.HostFunctionValue { - return interpreter.NewUnmeteredHostFunctionValue( - t.newEmulatorBlockchainFunctionType, - func(invocation interpreter.Invocation) interpreter.Value { - inter := invocation.Interpreter - locationRange := invocation.LocationRange - - // Create an `EmulatorBackend` - emulatorBackend := t.emulatorBackendType.newEmulatorBackend( - inter, - testFramework.NewEmulatorBackend(), - locationRange, - ) - - // Create a 'Blockchain' struct value, that wraps the emulator backend, - // by calling the constructor of 'Blockchain'. - - blockchainConstructor := getNestedTypeConstructorValue( - *invocation.Self, - testBlockchainTypeName, - ) - - blockchain, err := inter.InvokeExternally( - blockchainConstructor, - blockchainConstructor.Type, - []interpreter.Value{ - emulatorBackend, - }, - ) - - if err != nil { - panic(err) - } - - return blockchain - }, - ) -} - // 'Test.NewMatcher' function. // Constructs a matcher that test only 'AnyStruct'. // Accepts test function that accepts subtype of 'AnyStruct'. @@ -1035,8 +975,6 @@ func newTestContractType() *TestContractType { matcherType := ty.matcherType() matcherTestFunctionType := compositeFunctionType(matcherType, matcherTestFieldName) - blockchainType := ty.blockchainType() - // Test.assert() compositeType.Members.Set( testTypeAssertFunctionName, @@ -1070,19 +1008,6 @@ func newTestContractType() *TestContractType { ), ) - // Test.newEmulatorBlockchain() - newEmulatorBlockchainFunctionType := newTestTypeNewEmulatorBlockchainFunctionType(blockchainType) - compositeType.Members.Set( - testTypeNewEmulatorBlockchainFunctionName, - sema.NewUnmeteredPublicFunctionMember( - compositeType, - testTypeNewEmulatorBlockchainFunctionName, - newEmulatorBlockchainFunctionType, - testTypeNewEmulatorBlockchainFunctionDocString, - ), - ) - ty.newEmulatorBlockchainFunctionType = newEmulatorBlockchainFunctionType - // Test.readFile() compositeType.Members.Set( testTypeReadFileFunctionName, @@ -1233,6 +1158,7 @@ func newTestContractType() *TestContractType { ty.expectFailureFunction = newTestTypeExpectFailureFunction( expectFailureFunctionType, ) + compositeType.ResolveMembers() return ty } @@ -1273,23 +1199,6 @@ func (t *TestContractType) matcherType() *sema.CompositeType { return matcherType } -func (t *TestContractType) blockchainType() *sema.CompositeType { - typ, ok := t.CompositeType.NestedTypes.Get(testBlockchainTypeName) - if !ok { - panic(typeNotFoundError(testContractTypeName, testBlockchainTypeName)) - } - - matcherType, ok := typ.(*sema.CompositeType) - if !ok || matcherType.Kind != common.CompositeKindStructure { - panic(errors.NewUnexpectedError( - "invalid type for '%s'. expected struct type", - testMatcherTypeName, - )) - } - - return matcherType -} - func (t *TestContractType) NewTestContract( inter *interpreter.Interpreter, testFramework TestFramework, @@ -1300,9 +1209,14 @@ func (t *TestContractType) NewTestContract( error, ) { initializerTypes := t.InitializerTypes + emulatorBackend := t.emulatorBackendType.newEmulatorBackend( + inter, + testFramework.EmulatorBackend(), + interpreter.EmptyLocationRange, + ) value, err := inter.InvokeFunctionValue( constructor, - nil, + []interpreter.Value{emulatorBackend}, initializerTypes, initializerTypes, invocationRange, @@ -1318,8 +1232,6 @@ func (t *TestContractType) NewTestContract( compositeValue.Functions[testTypeAssertEqualFunctionName] = testTypeAssertEqualFunction compositeValue.Functions[testTypeFailFunctionName] = testTypeFailFunction compositeValue.Functions[testTypeExpectFunctionName] = t.expectFunction - compositeValue.Functions[testTypeNewEmulatorBlockchainFunctionName] = - t.newNewEmulatorBlockchainFunction(testFramework) compositeValue.Functions[testTypeReadFileFunctionName] = newTestTypeReadFileFunction(testFramework) diff --git a/runtime/stdlib/test_emulatorbackend.go b/runtime/stdlib/test_emulatorbackend.go index aca8706e56..1e087139ea 100644 --- a/runtime/stdlib/test_emulatorbackend.go +++ b/runtime/stdlib/test_emulatorbackend.go @@ -20,6 +20,8 @@ package stdlib import ( + "fmt" + "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/errors" "github.com/onflow/cadence/runtime/interpreter" @@ -41,7 +43,6 @@ type testEmulatorBackendType struct { executeNextTransactionFunctionType *sema.FunctionType commitBlockFunctionType *sema.FunctionType deployContractFunctionType *sema.FunctionType - useConfigFunctionType *sema.FunctionType logsFunctionType *sema.FunctionType serviceAccountFunctionType *sema.FunctionType eventsFunctionType *sema.FunctionType @@ -49,6 +50,7 @@ type testEmulatorBackendType struct { moveTimeFunctionType *sema.FunctionType createSnapshotFunctionType *sema.FunctionType loadSnapshotFunctionType *sema.FunctionType + getAccountFunctionType *sema.FunctionType } func newTestEmulatorBackendType( @@ -84,11 +86,6 @@ func newTestEmulatorBackendType( testEmulatorBackendTypeDeployContractFunctionName, ) - useConfigFunctionType := interfaceFunctionType( - blockchainBackendInterfaceType, - testEmulatorBackendTypeUseConfigFunctionName, - ) - logsFunctionType := interfaceFunctionType( blockchainBackendInterfaceType, testEmulatorBackendTypeLogsFunctionName, @@ -124,6 +121,11 @@ func newTestEmulatorBackendType( testEmulatorBackendTypeLoadSnapshotFunctionName, ) + getAccountFunctionType := interfaceFunctionType( + blockchainBackendInterfaceType, + testEmulatorBackendTypeGetAccountFunctionName, + ) + compositeType := &sema.CompositeType{ Identifier: testEmulatorBackendTypeName, Kind: common.CompositeKindStructure, @@ -170,12 +172,6 @@ func newTestEmulatorBackendType( deployContractFunctionType, testEmulatorBackendTypeDeployContractFunctionDocString, ), - sema.NewUnmeteredPublicFunctionMember( - compositeType, - testEmulatorBackendTypeUseConfigFunctionName, - useConfigFunctionType, - testEmulatorBackendTypeUseConfigFunctionDocString, - ), sema.NewUnmeteredPublicFunctionMember( compositeType, testEmulatorBackendTypeLogsFunctionName, @@ -218,6 +214,12 @@ func newTestEmulatorBackendType( loadSnapshotFunctionType, testEmulatorBackendTypeLoadSnapshotFunctionDocString, ), + sema.NewUnmeteredPublicFunctionMember( + compositeType, + testEmulatorBackendTypeGetAccountFunctionName, + getAccountFunctionType, + testEmulatorBackendTypeGetAccountFunctionDocString, + ), } compositeType.Members = sema.MembersAsMap(members) @@ -231,7 +233,6 @@ func newTestEmulatorBackendType( executeNextTransactionFunctionType: executeNextTransactionFunctionType, commitBlockFunctionType: commitBlockFunctionType, deployContractFunctionType: deployContractFunctionType, - useConfigFunctionType: useConfigFunctionType, logsFunctionType: logsFunctionType, serviceAccountFunctionType: serviceAccountFunctionType, eventsFunctionType: eventsFunctionType, @@ -239,6 +240,7 @@ func newTestEmulatorBackendType( moveTimeFunctionType: moveTimeFunctionType, createSnapshotFunctionType: createSnapshotFunctionType, loadSnapshotFunctionType: loadSnapshotFunctionType, + getAccountFunctionType: getAccountFunctionType, } } @@ -348,6 +350,47 @@ func newTestAccountValue( return accountValue } +// 'EmulatorBackend.getAccount' function + +const testEmulatorBackendTypeGetAccountFunctionName = "getAccount" + +const testEmulatorBackendTypeGetAccountFunctionDocString = ` +Returns the account for the given address. +` + +func (t *testEmulatorBackendType) newGetAccountFunction( + blockchain Blockchain, +) *interpreter.HostFunctionValue { + return interpreter.NewUnmeteredHostFunctionValue( + t.getAccountFunctionType, + func(invocation interpreter.Invocation) interpreter.Value { + address, ok := invocation.Arguments[0].(interpreter.AddressValue) + if !ok { + panic(errors.NewUnreachableError()) + } + + account, err := blockchain.GetAccount(address) + if err != nil { + msg := fmt.Sprintf("account with address: %s was not found", address) + panic(PanicError{ + Message: msg, + LocationRange: invocation.LocationRange, + }) + } + + inter := invocation.Interpreter + locationRange := invocation.LocationRange + + return newTestAccountValue( + blockchain, + inter, + locationRange, + account, + ) + }, + ) +} + // 'EmulatorBackend.addTransaction' function const testEmulatorBackendTypeAddTransactionFunctionName = "addTransaction" @@ -509,22 +552,14 @@ func (t *testEmulatorBackendType) newDeployContractFunction( panic(errors.NewUnreachableError()) } - // Contract code - code, ok := invocation.Arguments[1].(*interpreter.StringValue) - if !ok { - panic(errors.NewUnreachableError()) - } - - // authorizer - accountValue, ok := invocation.Arguments[2].(interpreter.MemberAccessibleValue) + // Contract file path + path, ok := invocation.Arguments[1].(*interpreter.StringValue) if !ok { panic(errors.NewUnreachableError()) } - account := accountFromValue(inter, accountValue, invocation.LocationRange) - // Contract init arguments - args, err := arrayValueToSlice(inter, invocation.Arguments[3]) + args, err := arrayValueToSlice(inter, invocation.Arguments[2]) if err != nil { panic(err) } @@ -532,8 +567,7 @@ func (t *testEmulatorBackendType) newDeployContractFunction( err = blockchain.DeployContract( inter, name.Str, - code.Str, - account, + path.Str, args, ) @@ -542,65 +576,6 @@ func (t *testEmulatorBackendType) newDeployContractFunction( ) } -// 'EmulatorBackend.useConfiguration' function - -const testEmulatorBackendTypeUseConfigFunctionName = "useConfiguration" - -const testEmulatorBackendTypeUseConfigFunctionDocString = ` -Set the configuration to be used by the blockchain. -Overrides any existing configuration. -` - -func (t *testEmulatorBackendType) newUseConfigFunction( - blockchain Blockchain, -) *interpreter.HostFunctionValue { - return interpreter.NewUnmeteredHostFunctionValue( - t.useConfigFunctionType, - func(invocation interpreter.Invocation) interpreter.Value { - inter := invocation.Interpreter - - // configurations - configsValue, ok := invocation.Arguments[0].(*interpreter.CompositeValue) - if !ok { - panic(errors.NewUnreachableError()) - } - - addresses, ok := configsValue.GetMember( - inter, - invocation.LocationRange, - addressesFieldName, - ).(*interpreter.DictionaryValue) - if !ok { - panic(errors.NewUnreachableError()) - } - - mapping := make(map[string]common.Address, addresses.Count()) - - addresses.Iterate(inter, func(locationValue, addressValue interpreter.Value) bool { - location, ok := locationValue.(*interpreter.StringValue) - if !ok { - panic(errors.NewUnreachableError()) - } - - address, ok := addressValue.(interpreter.AddressValue) - if !ok { - panic(errors.NewUnreachableError()) - } - - mapping[location.Str] = common.Address(address) - - return true - }) - - blockchain.UseConfiguration(&Configuration{ - Addresses: mapping, - }) - - return interpreter.Void - }, - ) -} - // 'EmulatorBackend.logs' function const testEmulatorBackendTypeLogsFunctionName = "logs" @@ -846,10 +821,6 @@ func (t *testEmulatorBackendType) newEmulatorBackend( Name: testEmulatorBackendTypeDeployContractFunctionName, Value: t.newDeployContractFunction(blockchain), }, - { - Name: testEmulatorBackendTypeUseConfigFunctionName, - Value: t.newUseConfigFunction(blockchain), - }, { Name: testEmulatorBackendTypeLogsFunctionName, Value: t.newLogsFunction(blockchain), @@ -878,6 +849,10 @@ func (t *testEmulatorBackendType) newEmulatorBackend( Name: testEmulatorBackendTypeLoadSnapshotFunctionName, Value: t.newLoadSnapshotFunction(blockchain), }, + { + Name: testEmulatorBackendTypeGetAccountFunctionName, + Value: t.newGetAccountFunction(blockchain), + }, } // TODO: Use SimpleCompositeValue diff --git a/runtime/stdlib/test_test.go b/runtime/stdlib/test_test.go index f16b66075d..6a3a2e4af4 100644 --- a/runtime/stdlib/test_test.go +++ b/runtime/stdlib/test_test.go @@ -16,7 +16,8 @@ * limitations under the License. */ -package stdlib +// This is in order to avoid cyclic import errors with runtime package +package stdlib_test import ( "errors" @@ -26,6 +27,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/onflow/cadence/runtime" "github.com/onflow/cadence/runtime/activations" "github.com/onflow/cadence/runtime/ast" "github.com/onflow/cadence/runtime/common" @@ -33,18 +35,24 @@ import ( "github.com/onflow/cadence/runtime/interpreter" "github.com/onflow/cadence/runtime/parser" "github.com/onflow/cadence/runtime/sema" + "github.com/onflow/cadence/runtime/stdlib" "github.com/onflow/cadence/runtime/tests/checker" "github.com/onflow/cadence/runtime/tests/utils" ) func newTestContractInterpreter(t *testing.T, code string) (*interpreter.Interpreter, error) { - return newTestContractInterpreterWithTestFramework(t, code, nil) + testFramework := &mockedTestFramework{ + emulatorBackend: func() stdlib.Blockchain { + return &mockedBlockchain{} + }, + } + return newTestContractInterpreterWithTestFramework(t, code, testFramework) } func newTestContractInterpreterWithTestFramework( t *testing.T, code string, - testFramework TestFramework, + testFramework stdlib.TestFramework, ) (*interpreter.Interpreter, error) { program, err := parser.ParseProgram( nil, @@ -54,8 +62,8 @@ func newTestContractInterpreterWithTestFramework( require.NoError(t, err) activation := sema.NewVariableActivation(sema.BaseValueActivation) - activation.DeclareValue(AssertFunction) - activation.DeclareValue(PanicFunction) + activation.DeclareValue(stdlib.AssertFunction) + activation.DeclareValue(stdlib.PanicFunction) checker, err := sema.NewChecker( program, @@ -72,15 +80,15 @@ func newTestContractInterpreterWithTestFramework( sema.Import, error, ) { - if importedLocation == TestContractLocation { + if importedLocation == stdlib.TestContractLocation { return sema.ElaborationImport{ - Elaboration: GetTestContractType().Checker.Elaboration, + Elaboration: stdlib.GetTestContractType().Checker.Elaboration, }, nil } return nil, errors.New("invalid import") }, - ContractValueHandler: TestCheckerContractValueHandler, + ContractValueHandler: stdlib.TestCheckerContractValueHandler, }, ) require.NoError(t, err) @@ -90,13 +98,13 @@ func newTestContractInterpreterWithTestFramework( return nil, err } - storage := newUnmeteredInMemoryStorage() + storage := interpreter.NewInMemoryStorage(nil) var uuid uint64 = 0 baseActivation := activations.NewActivation(nil, interpreter.BaseActivation) - interpreter.Declare(baseActivation, AssertFunction) - interpreter.Declare(baseActivation, PanicFunction) + interpreter.Declare(baseActivation, stdlib.AssertFunction) + interpreter.Declare(baseActivation, stdlib.PanicFunction) inter, err := interpreter.NewInterpreter( interpreter.ProgramFromChecker(checker), @@ -105,8 +113,8 @@ func newTestContractInterpreterWithTestFramework( Storage: storage, BaseActivation: baseActivation, ImportLocationHandler: func(inter *interpreter.Interpreter, location common.Location) interpreter.Import { - if location == TestContractLocation { - program := interpreter.ProgramFromChecker(GetTestContractType().Checker) + if location == stdlib.TestContractLocation { + program := interpreter.ProgramFromChecker(stdlib.GetTestContractType().Checker) subInterpreter, err := inter.NewSubInterpreter(program, location) if err != nil { panic(err) @@ -118,7 +126,7 @@ func newTestContractInterpreterWithTestFramework( return nil }, - ContractValueHandler: NewTestInterpreterContractValueHandler(testFramework), + ContractValueHandler: stdlib.NewTestInterpreterContractValueHandler(testFramework), UUIDHandler: func() (uint64, error) { uuid++ return uuid, nil @@ -142,7 +150,8 @@ func TestTestNewMatcher(t *testing.T) { script := ` import Test - access(all) fun test(): Bool { + access(all) + fun test(): Bool { let matcher = Test.newMatcher(fun (_ value: AnyStruct): Bool { if !value.getType().isSubtype(of: Type()) { return false @@ -169,7 +178,8 @@ func TestTestNewMatcher(t *testing.T) { script := ` import Test - access(all) fun test(): Bool { + access(all) + fun test(): Bool { let matcher = Test.newMatcher(fun (_ value: Int): Bool { return value == 7 @@ -193,7 +203,8 @@ func TestTestNewMatcher(t *testing.T) { script := ` import Test - access(all) fun test() { + access(all) + fun test() { let matcher = Test.newMatcher(fun (_ value: Int): Bool { return (value + 7) == 4 @@ -218,7 +229,8 @@ func TestTestNewMatcher(t *testing.T) { script := ` import Test - access(all) fun test(): Bool { + access(all) + fun test(): Bool { let matcher = Test.newMatcher(fun (_ value: &Foo): Bool { return value.a == 4 @@ -233,8 +245,11 @@ func TestTestNewMatcher(t *testing.T) { return res } - access(all) resource Foo { - access(all) let a: Int + access(all) + resource Foo { + + access(all) + let a: Int init(_ a: Int) { self.a = a @@ -254,18 +269,20 @@ func TestTestNewMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test() { + access(all) + fun test() { - let matcher = Test.newMatcher(fun (_ value: @Foo): Bool { - destroy value - return true - }) - } + let matcher = Test.newMatcher(fun (_ value: @Foo): Bool { + destroy value + return true + }) + } - access(all) resource Foo {} - ` + access(all) + resource Foo {} + ` _, err := newTestContractInterpreter(t, script) @@ -277,17 +294,18 @@ func TestTestNewMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test(): Bool { + access(all) + fun test(): Bool { - let matcher = Test.newMatcher(fun (_ value: Int): Bool { - return value == 7 - }) + let matcher = Test.newMatcher(fun (_ value: Int): Bool { + return value == 7 + }) - return matcher.test(7) - } - ` + return matcher.test(7) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -301,15 +319,16 @@ func TestTestNewMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test() { + access(all) + fun test() { - let matcher = Test.newMatcher(fun (_ value: Int): Bool { - return value == 7 - }) - } - ` + let matcher = Test.newMatcher(fun (_ value: Int): Bool { + return value == 7 + }) + } + ` _, err := newTestContractInterpreter(t, script) @@ -322,24 +341,25 @@ func TestTestNewMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test() { + access(all) + fun test() { - let matcher1 = Test.newMatcher(fun (_ value: Int): Bool { - return (value + 5) == 10 - }) + let matcher1 = Test.newMatcher(fun (_ value: Int): Bool { + return (value + 5) == 10 + }) - let matcher2 = Test.newMatcher(fun (_ value: String): Bool { - return value.length == 10 - }) + let matcher2 = Test.newMatcher(fun (_ value: String): Bool { + return value.length == 10 + }) - let matcher3 = matcher1.and(matcher2) + let matcher3 = matcher1.and(matcher2) - // Invoke with a type that matches to only one matcher - matcher3.test(5) - } - ` + // Invoke with a type that matches to only one matcher + matcher3.test(5) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -360,7 +380,8 @@ func TestTestEqualMatcher(t *testing.T) { script := ` import Test - access(all) fun test() { + access(all) + fun test() { Test.equal(1) } ` @@ -378,7 +399,8 @@ func TestTestEqualMatcher(t *testing.T) { script := ` import Test - access(all) fun test(): Bool { + access(all) + fun test(): Bool { let matcher = Test.equal(1) return matcher.test(1) } @@ -398,13 +420,15 @@ func TestTestEqualMatcher(t *testing.T) { script := ` import Test - access(all) fun test(): Bool { + access(all) + fun test(): Bool { let f = Foo() let matcher = Test.equal(f) return matcher.test(f) } - access(all) struct Foo {} + access(all) + struct Foo {} ` inter, err := newTestContractInterpreter(t, script) @@ -421,13 +445,15 @@ func TestTestEqualMatcher(t *testing.T) { script := ` import Test - access(all) fun test(): Bool { + access(all) + fun test(): Bool { let f <- create Foo() let matcher = Test.equal(<-f) return matcher.test(<- create Foo()) } - access(all) resource Foo {} + access(all) + resource Foo {} ` _, err := newTestContractInterpreter(t, script) @@ -444,7 +470,8 @@ func TestTestEqualMatcher(t *testing.T) { script := ` import Test - access(all) fun test() { + access(all) + fun test() { let matcher = Test.equal("hello") } ` @@ -462,7 +489,8 @@ func TestTestEqualMatcher(t *testing.T) { script := ` import Test - access(all) fun test() { + access(all) + fun test() { let matcher = Test.equal(1) } ` @@ -480,7 +508,8 @@ func TestTestEqualMatcher(t *testing.T) { script := ` import Test - access(all) fun test(): Bool { + access(all) + fun test(): Bool { let one = Test.equal(1) let two = Test.equal(2) @@ -505,7 +534,8 @@ func TestTestEqualMatcher(t *testing.T) { script := ` import Test - access(all) fun test(): Bool { + access(all) + fun test(): Bool { let one = Test.equal(1) let two = Test.equal(2) @@ -529,7 +559,8 @@ func TestTestEqualMatcher(t *testing.T) { script := ` import Test - access(all) fun test(): Bool { + access(all) + fun test(): Bool { let one = Test.equal(1) let two = Test.equal(2) @@ -551,24 +582,26 @@ func TestTestEqualMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun testMatch(): Bool { - let one = Test.equal(1) + access(all) + fun testMatch(): Bool { + let one = Test.equal(1) - let notOne = Test.not(one) + let notOne = Test.not(one) - return notOne.test(2) - } + return notOne.test(2) + } - access(all) fun testNoMatch(): Bool { - let one = Test.equal(1) + access(all) + fun testNoMatch(): Bool { + let one = Test.equal(1) - let notOne = Test.not(one) + let notOne = Test.not(one) - return notOne.test(1) - } - ` + return notOne.test(1) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -588,7 +621,8 @@ func TestTestEqualMatcher(t *testing.T) { script := ` import Test - access(all) fun test(): Bool { + access(all) + fun test(): Bool { let one = Test.equal(1) let two = Test.equal(2) let three = Test.equal(3) @@ -613,7 +647,8 @@ func TestTestEqualMatcher(t *testing.T) { script := ` import Test - access(all) fun test(): Bool { + access(all) + fun test(): Bool { let foo <- create Foo() let bar <- create Bar() @@ -626,8 +661,10 @@ func TestTestEqualMatcher(t *testing.T) { && matcher.test(<-create Bar()) } - access(all) resource Foo {} - access(all) resource Bar {} + access(all) + resource Foo {} + access(all) + resource Bar {} ` _, err := newTestContractInterpreter(t, script) @@ -645,7 +682,8 @@ func TestTestEqualMatcher(t *testing.T) { script := ` import Test - access(all) fun test(): Bool { + access(all) + fun test(): Bool { let foo <- create Foo() let bar <- create Bar() @@ -657,8 +695,10 @@ func TestTestEqualMatcher(t *testing.T) { return matcher.test(<-create Foo()) } - access(all) resource Foo {} - access(all) resource Bar {} + access(all) + resource Foo {} + access(all) + resource Bar {} ` _, err := newTestContractInterpreter(t, script) @@ -678,12 +718,13 @@ func TestAssertEqual(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test() { - Test.assertEqual("this string", "this string") - } - ` + access(all) + fun test() { + Test.assertEqual("this string", "this string") + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -696,19 +737,20 @@ func TestAssertEqual(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test() { - Test.assertEqual(15, 21) - } - ` + access(all) + fun test() { + Test.assertEqual(15, 21) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) _, err = inter.Invoke("test") require.Error(t, err) - assert.ErrorAs(t, err, &AssertionError{}) + assert.ErrorAs(t, err, &stdlib.AssertionError{}) assert.ErrorContains( t, err, @@ -720,19 +762,20 @@ func TestAssertEqual(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test() { - Test.assertEqual(true, 1) - } - ` + access(all) + fun test() { + Test.assertEqual(true, 1) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) _, err = inter.Invoke("test") require.Error(t, err) - assert.ErrorAs(t, err, &AssertionError{}) + assert.ErrorAs(t, err, &stdlib.AssertionError{}) assert.ErrorContains( t, err, @@ -744,20 +787,22 @@ func TestAssertEqual(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun testEqual() { - let expected = Address(0xf8d6e0586b0a20c7) - let actual = Address(0xf8d6e0586b0a20c7) - Test.assertEqual(expected, actual) - } + access(all) + fun testEqual() { + let expected = Address(0xf8d6e0586b0a20c7) + let actual = Address(0xf8d6e0586b0a20c7) + Test.assertEqual(expected, actual) + } - access(all) fun testNotEqual() { - let expected = Address(0xf8d6e0586b0a20c7) - let actual = Address(0xee82856bf20e2aa6) - Test.assertEqual(expected, actual) - } - ` + access(all) + fun testNotEqual() { + let expected = Address(0xf8d6e0586b0a20c7) + let actual = Address(0xee82856bf20e2aa6) + Test.assertEqual(expected, actual) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -767,7 +812,7 @@ func TestAssertEqual(t *testing.T) { _, err = inter.Invoke("testNotEqual") require.Error(t, err) - assert.ErrorAs(t, err, &AssertionError{}) + assert.ErrorAs(t, err, &stdlib.AssertionError{}) assert.ErrorContains( t, err, @@ -779,28 +824,33 @@ func TestAssertEqual(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) struct Foo { - access(all) let answer: Int + access(all) + struct Foo { + + access(all) + let answer: Int - init(answer: Int) { - self.answer = answer - } - } + init(answer: Int) { + self.answer = answer + } + } - access(all) fun testEqual() { - let expected = Foo(answer: 42) - let actual = Foo(answer: 42) - Test.assertEqual(expected, actual) - } + access(all) + fun testEqual() { + let expected = Foo(answer: 42) + let actual = Foo(answer: 42) + Test.assertEqual(expected, actual) + } - access(all) fun testNotEqual() { - let expected = Foo(answer: 42) - let actual = Foo(answer: 420) - Test.assertEqual(expected, actual) - } - ` + access(all) + fun testNotEqual() { + let expected = Foo(answer: 42) + let actual = Foo(answer: 420) + Test.assertEqual(expected, actual) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -810,7 +860,7 @@ func TestAssertEqual(t *testing.T) { _, err = inter.Invoke("testNotEqual") require.Error(t, err) - assert.ErrorAs(t, err, &AssertionError{}) + assert.ErrorAs(t, err, &stdlib.AssertionError{}) assert.ErrorContains( t, err, @@ -822,20 +872,22 @@ func TestAssertEqual(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun testEqual() { - let expected = [1, 2, 3] - let actual = [1, 2, 3] - Test.assertEqual(expected, actual) - } + access(all) + fun testEqual() { + let expected = [1, 2, 3] + let actual = [1, 2, 3] + Test.assertEqual(expected, actual) + } - access(all) fun testNotEqual() { - let expected = [1, 2, 3] - let actual = [1, 2] - Test.assertEqual(expected, actual) - } - ` + access(all) + fun testNotEqual() { + let expected = [1, 2, 3] + let actual = [1, 2] + Test.assertEqual(expected, actual) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -845,7 +897,7 @@ func TestAssertEqual(t *testing.T) { _, err = inter.Invoke("testNotEqual") require.Error(t, err) - assert.ErrorAs(t, err, &AssertionError{}) + assert.ErrorAs(t, err, &stdlib.AssertionError{}) assert.ErrorContains( t, err, @@ -857,20 +909,22 @@ func TestAssertEqual(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun testEqual() { - let expected = {1: true, 2: false, 3: true} - let actual = {1: true, 2: false, 3: true} - Test.assertEqual(expected, actual) - } + access(all) + fun testEqual() { + let expected = {1: true, 2: false, 3: true} + let actual = {1: true, 2: false, 3: true} + Test.assertEqual(expected, actual) + } - access(all) fun testNotEqual() { - let expected = {1: true, 2: false} - let actual = {1: true, 2: true} - Test.assertEqual(expected, actual) - } - ` + access(all) + fun testNotEqual() { + let expected = {1: true, 2: false} + let actual = {1: true, 2: true} + Test.assertEqual(expected, actual) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -880,11 +934,11 @@ func TestAssertEqual(t *testing.T) { _, err = inter.Invoke("testNotEqual") require.Error(t, err) - assert.ErrorAs(t, err, &AssertionError{}) + assert.ErrorAs(t, err, &stdlib.AssertionError{}) assert.ErrorContains( t, err, - "not equal: expected: {2: false, 1: true}, actual: {2: true, 1: true}", + "not equal: expected: {1: true, 2: false}, actual: {2: true, 1: true}", ) }) @@ -892,16 +946,18 @@ func TestAssertEqual(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test() { - let f1 <- create Foo() - let f2 <- create Foo() - Test.assertEqual(<-f1, <-f2) - } + access(all) + fun test() { + let f1 <- create Foo() + let f2 <- create Foo() + Test.assertEqual(<-f1, <-f2) + } - access(all) resource Foo {} - ` + access(all) + resource Foo {} + ` _, err := newTestContractInterpreter(t, script) @@ -914,17 +970,20 @@ func TestAssertEqual(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test() { - let foo <- create Foo() - let bar = Bar() - Test.assertEqual(<-foo, bar) - } + access(all) + fun test() { + let foo <- create Foo() + let bar = Bar() + Test.assertEqual(<-foo, bar) + } - access(all) resource Foo {} - access(all) struct Bar {} - ` + access(all) + resource Foo {} + access(all) + struct Bar {} + ` _, err := newTestContractInterpreter(t, script) @@ -936,17 +995,20 @@ func TestAssertEqual(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test() { - let foo = Foo() - let bar <- create Bar() - Test.expect(foo, Test.equal(<-bar)) - } + access(all) + fun test() { + let foo = Foo() + let bar <- create Bar() + Test.expect(foo, Test.equal(<-bar)) + } - access(all) struct Foo {} - access(all) resource Bar {} - ` + access(all) + struct Foo {} + access(all) + resource Bar {} + ` _, err := newTestContractInterpreter(t, script) @@ -963,32 +1025,34 @@ func TestTestBeSucceededMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun testMatch(): Bool { - let successful = Test.beSucceeded() + access(all) + fun testMatch(): Bool { + let successful = Test.beSucceeded() - let scriptResult = Test.ScriptResult( - status: Test.ResultStatus.succeeded, - returnValue: 42, - error: nil - ) + let scriptResult = Test.ScriptResult( + status: Test.ResultStatus.succeeded, + returnValue: 42, + error: nil + ) - return successful.test(scriptResult) - } + return successful.test(scriptResult) + } - access(all) fun testNoMatch(): Bool { - let successful = Test.beSucceeded() + access(all) + fun testNoMatch(): Bool { + let successful = Test.beSucceeded() - let scriptResult = Test.ScriptResult( - status: Test.ResultStatus.failed, - returnValue: nil, - error: Test.Error("Exceeding limit") - ) + let scriptResult = Test.ScriptResult( + status: Test.ResultStatus.failed, + returnValue: nil, + error: Test.Error("Exceeding limit") + ) - return successful.test(scriptResult) - } - ` + return successful.test(scriptResult) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1006,30 +1070,32 @@ func TestTestBeSucceededMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun testMatch(): Bool { - let successful = Test.beSucceeded() + access(all) + fun testMatch(): Bool { + let successful = Test.beSucceeded() - let transactionResult = Test.TransactionResult( - status: Test.ResultStatus.succeeded, - error: nil - ) + let transactionResult = Test.TransactionResult( + status: Test.ResultStatus.succeeded, + error: nil + ) - return successful.test(transactionResult) - } + return successful.test(transactionResult) + } - access(all) fun testNoMatch(): Bool { - let successful = Test.beSucceeded() + access(all) + fun testNoMatch(): Bool { + let successful = Test.beSucceeded() - let transactionResult = Test.TransactionResult( - status: Test.ResultStatus.failed, - error: Test.Error("Exceeded Limit") - ) + let transactionResult = Test.TransactionResult( + status: Test.ResultStatus.failed, + error: Test.Error("Exceeded Limit") + ) - return successful.test(transactionResult) - } - ` + return successful.test(transactionResult) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1047,14 +1113,15 @@ func TestTestBeSucceededMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test(): Bool { - let successful = Test.beSucceeded() + access(all) + fun test(): Bool { + let successful = Test.beSucceeded() - return successful.test("hello") - } - ` + return successful.test("hello") + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1072,32 +1139,34 @@ func TestTestBeFailedMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun testMatch(): Bool { - let failed = Test.beFailed() + access(all) + fun testMatch(): Bool { + let failed = Test.beFailed() - let scriptResult = Test.ScriptResult( - status: Test.ResultStatus.failed, - returnValue: nil, - error: Test.Error("Exceeding limit") - ) + let scriptResult = Test.ScriptResult( + status: Test.ResultStatus.failed, + returnValue: nil, + error: Test.Error("Exceeding limit") + ) - return failed.test(scriptResult) - } + return failed.test(scriptResult) + } - access(all) fun testNoMatch(): Bool { - let failed = Test.beFailed() + access(all) + fun testNoMatch(): Bool { + let failed = Test.beFailed() - let scriptResult = Test.ScriptResult( - status: Test.ResultStatus.succeeded, - returnValue: 42, - error: nil - ) + let scriptResult = Test.ScriptResult( + status: Test.ResultStatus.succeeded, + returnValue: 42, + error: nil + ) - return failed.test(scriptResult) - } - ` + return failed.test(scriptResult) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1115,30 +1184,32 @@ func TestTestBeFailedMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun testMatch(): Bool { - let failed = Test.beFailed() + access(all) + fun testMatch(): Bool { + let failed = Test.beFailed() - let transactionResult = Test.TransactionResult( - status: Test.ResultStatus.failed, - error: Test.Error("Exceeding limit") - ) + let transactionResult = Test.TransactionResult( + status: Test.ResultStatus.failed, + error: Test.Error("Exceeding limit") + ) - return failed.test(transactionResult) - } + return failed.test(transactionResult) + } - access(all) fun testNoMatch(): Bool { - let failed = Test.beFailed() + access(all) + fun testNoMatch(): Bool { + let failed = Test.beFailed() - let transactionResult = Test.TransactionResult( - status: Test.ResultStatus.succeeded, - error: nil - ) + let transactionResult = Test.TransactionResult( + status: Test.ResultStatus.succeeded, + error: nil + ) - return failed.test(transactionResult) - } - ` + return failed.test(transactionResult) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1156,14 +1227,15 @@ func TestTestBeFailedMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test(): Bool { - let failed = Test.beFailed() + access(all) + fun test(): Bool { + let failed = Test.beFailed() - return failed.test([]) - } - ` + return failed.test([]) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1215,7 +1287,7 @@ func TestTestAssertErrorMatcher(t *testing.T) { Test.assertError(result, errorMessage: "exceeding limit") } - ` + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1267,7 +1339,7 @@ func TestTestAssertErrorMatcher(t *testing.T) { Test.assertError(result, errorMessage: "exceeding limit") } - ` + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1293,20 +1365,22 @@ func TestTestBeNilMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun testMatch(): Bool { - let isNil = Test.beNil() + access(all) + fun testMatch(): Bool { + let isNil = Test.beNil() - return isNil.test(nil) - } + return isNil.test(nil) + } - access(all) fun testNoMatch(): Bool { - let isNil = Test.beNil() + access(all) + fun testNoMatch(): Bool { + let isNil = Test.beNil() - return isNil.test([1, 2]) - } - ` + return isNil.test([1, 2]) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1329,20 +1403,22 @@ func TestTestBeEmptyMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun testMatch(): Bool { - let emptyArray = Test.beEmpty() + access(all) + fun testMatch(): Bool { + let emptyArray = Test.beEmpty() - return emptyArray.test([]) - } + return emptyArray.test([]) + } - access(all) fun testNoMatch(): Bool { - let emptyArray = Test.beEmpty() + access(all) + fun testNoMatch(): Bool { + let emptyArray = Test.beEmpty() - return emptyArray.test([42, 23, 31]) - } - ` + return emptyArray.test([42, 23, 31]) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1360,22 +1436,24 @@ func TestTestBeEmptyMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun testMatch(): Bool { - let emptyDict = Test.beEmpty() - let dict: {Bool: Int} = {} + access(all) + fun testMatch(): Bool { + let emptyDict = Test.beEmpty() + let dict: {Bool: Int} = {} - return emptyDict.test(dict) - } + return emptyDict.test(dict) + } - access(all) fun testNoMatch(): Bool { - let emptyDict = Test.beEmpty() - let dict: {Bool: Int} = {true: 1, false: 0} + access(all) + fun testNoMatch(): Bool { + let emptyDict = Test.beEmpty() + let dict: {Bool: Int} = {true: 1, false: 0} - return emptyDict.test(dict) - } - ` + return emptyDict.test(dict) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1393,14 +1471,15 @@ func TestTestBeEmptyMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test(): Bool { - let emptyDict = Test.beEmpty() + access(all) + fun test(): Bool { + let emptyDict = Test.beEmpty() - return emptyDict.test("empty") - } - ` + return emptyDict.test("empty") + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1420,20 +1499,22 @@ func TestTestHaveElementCountMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun testMatch(): Bool { - let hasThreeElements = Test.haveElementCount(3) + access(all) + fun testMatch(): Bool { + let hasThreeElements = Test.haveElementCount(3) - return hasThreeElements.test([42, 23, 31]) - } + return hasThreeElements.test([42, 23, 31]) + } - access(all) fun testNoMatch(): Bool { - let hasThreeElements = Test.haveElementCount(3) + access(all) + fun testNoMatch(): Bool { + let hasThreeElements = Test.haveElementCount(3) - return hasThreeElements.test([42]) - } - ` + return hasThreeElements.test([42]) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1451,22 +1532,24 @@ func TestTestHaveElementCountMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun testMatch(): Bool { - let hasTwoElements = Test.haveElementCount(2) - let dict: {Bool: Int} = {true: 1, false: 0} + access(all) + fun testMatch(): Bool { + let hasTwoElements = Test.haveElementCount(2) + let dict: {Bool: Int} = {true: 1, false: 0} - return hasTwoElements.test(dict) - } + return hasTwoElements.test(dict) + } - access(all) fun testNoMatch(): Bool { - let hasTwoElements = Test.haveElementCount(2) - let dict: {Bool: Int} = {} + access(all) + fun testNoMatch(): Bool { + let hasTwoElements = Test.haveElementCount(2) + let dict: {Bool: Int} = {} - return hasTwoElements.test(dict) - } - ` + return hasTwoElements.test(dict) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1484,14 +1567,15 @@ func TestTestHaveElementCountMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test(): Bool { - let hasTwoElements = Test.haveElementCount(2) + access(all) + fun test(): Bool { + let hasTwoElements = Test.haveElementCount(2) - return hasTwoElements.test("two") - } - ` + return hasTwoElements.test("two") + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1511,20 +1595,22 @@ func TestTestContainMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun testMatch(): Bool { - let containsTwenty = Test.contain(20) + access(all) + fun testMatch(): Bool { + let containsTwenty = Test.contain(20) - return containsTwenty.test([42, 20, 31]) - } + return containsTwenty.test([42, 20, 31]) + } - access(all) fun testNoMatch(): Bool { - let containsTwenty = Test.contain(20) + access(all) + fun testNoMatch(): Bool { + let containsTwenty = Test.contain(20) - return containsTwenty.test([42]) - } - ` + return containsTwenty.test([42]) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1542,22 +1628,24 @@ func TestTestContainMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun testMatch(): Bool { - let containsFalse = Test.contain(false) - let dict: {Bool: Int} = {true: 1, false: 0} + access(all) + fun testMatch(): Bool { + let containsFalse = Test.contain(false) + let dict: {Bool: Int} = {true: 1, false: 0} - return containsFalse.test(dict) - } + return containsFalse.test(dict) + } - access(all) fun testNoMatch(): Bool { - let containsFive = Test.contain(5) - let dict: {Int: Bool} = {1: true, 0: false} + access(all) + fun testNoMatch(): Bool { + let containsFive = Test.contain(5) + let dict: {Int: Bool} = {1: true, 0: false} - return containsFive.test(dict) - } - ` + return containsFive.test(dict) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1575,14 +1663,15 @@ func TestTestContainMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test(): Bool { - let containsFalse = Test.contain(false) + access(all) + fun test(): Bool { + let containsFalse = Test.contain(false) - return containsFalse.test("false") - } - ` + return containsFalse.test("false") + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1602,20 +1691,22 @@ func TestTestBeGreaterThanMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun testMatch(): Bool { - let greaterThanFive = Test.beGreaterThan(5) + access(all) + fun testMatch(): Bool { + let greaterThanFive = Test.beGreaterThan(5) - return greaterThanFive.test(7) - } + return greaterThanFive.test(7) + } - access(all) fun testNoMatch(): Bool { - let greaterThanFive = Test.beGreaterThan(5) + access(all) + fun testNoMatch(): Bool { + let greaterThanFive = Test.beGreaterThan(5) - return greaterThanFive.test(2) - } - ` + return greaterThanFive.test(2) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1633,14 +1724,15 @@ func TestTestBeGreaterThanMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test(): Bool { - let greaterThanFive = Test.beGreaterThan(5) + access(all) + fun test(): Bool { + let greaterThanFive = Test.beGreaterThan(5) - return greaterThanFive.test("7") - } - ` + return greaterThanFive.test("7") + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1658,20 +1750,22 @@ func TestTestBeLessThanMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun testMatch(): Bool { - let lessThanSeven = Test.beLessThan(7) + access(all) + fun testMatch(): Bool { + let lessThanSeven = Test.beLessThan(7) - return lessThanSeven.test(5) - } + return lessThanSeven.test(5) + } - access(all) fun testNoMatch(): Bool { - let lessThanSeven = Test.beLessThan(7) + access(all) + fun testNoMatch(): Bool { + let lessThanSeven = Test.beLessThan(7) - return lessThanSeven.test(9) - } - ` + return lessThanSeven.test(9) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1689,14 +1783,15 @@ func TestTestBeLessThanMatcher(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test(): Bool { - let lessThanSeven = Test.beLessThan(7) + access(all) + fun test(): Bool { + let lessThanSeven = Test.beLessThan(7) - return lessThanSeven.test(true) - } - ` + return lessThanSeven.test(true) + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1716,7 +1811,8 @@ func TestTestExpect(t *testing.T) { script := ` import Test - access(all) fun test() { + access(all) + fun test() { Test.expect("this string", Test.equal("this string")) } ` @@ -1734,7 +1830,8 @@ func TestTestExpect(t *testing.T) { script := ` import Test - access(all) fun test() { + access(all) + fun test() { Test.expect("this string", Test.equal("other string")) } ` @@ -1745,11 +1842,11 @@ func TestTestExpect(t *testing.T) { _, err = inter.Invoke("test") require.Error(t, err) - assertionErr := &AssertionError{} + assertionErr := &stdlib.AssertionError{} assert.ErrorAs(t, err, assertionErr) assert.Equal(t, "given value is: \"this string\"", assertionErr.Message) assert.Equal(t, "test", assertionErr.LocationRange.Location.String()) - assert.Equal(t, 5, assertionErr.LocationRange.StartPosition().Line) + assert.Equal(t, 6, assertionErr.LocationRange.StartPosition().Line) }) t.Run("different types", func(t *testing.T) { @@ -1758,7 +1855,8 @@ func TestTestExpect(t *testing.T) { script := ` import Test - access(all) fun test() { + access(all) + fun test() { Test.expect("string", Test.equal(1)) } ` @@ -1777,7 +1875,8 @@ func TestTestExpect(t *testing.T) { script := ` import Test - access(all) fun test() { + access(all) + fun test() { Test.expect("hello", Test.equal("hello")) } ` @@ -1795,7 +1894,8 @@ func TestTestExpect(t *testing.T) { script := ` import Test - access(all) fun test() { + access(all) + fun test() { Test.expect("string", Test.equal(1)) } ` @@ -1813,13 +1913,15 @@ func TestTestExpect(t *testing.T) { script := ` import Test - access(all) fun test() { + access(all) + fun test() { let f1 <- create Foo() let f2 <- create Foo() Test.expect(<-f1, Test.equal(<-f2)) } - access(all) resource Foo {} + access(all) + resource Foo {} ` _, err := newTestContractInterpreter(t, script) @@ -1835,14 +1937,17 @@ func TestTestExpect(t *testing.T) { script := ` import Test - access(all) fun test() { + access(all) + fun test() { let foo <- create Foo() let bar = Bar() Test.expect(<-foo, Test.equal(bar)) } - access(all) resource Foo {} - access(all) struct Bar {} + access(all) + resource Foo {} + access(all) + struct Bar {} ` _, err := newTestContractInterpreter(t, script) @@ -1857,14 +1962,17 @@ func TestTestExpect(t *testing.T) { script := ` import Test - access(all) fun test() { + access(all) + fun test() { let foo = Foo() let bar <- create Bar() Test.expect(foo, Test.equal(<-bar)) } - access(all) struct Foo {} - access(all) resource Bar {} + access(all) + struct Foo {} + access(all) + resource Bar {} ` _, err := newTestContractInterpreter(t, script) @@ -1882,30 +1990,33 @@ func TestTestExpectFailure(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test() { - let foo = Foo(answer: 42) - Test.expectFailure(fun(): Void { - foo.correctAnswer(42) - }, errorMessageSubstring: "wrong answer!") - } + access(all) + fun test() { + let foo = Foo(answer: 42) + Test.expectFailure(fun(): Void { + foo.correctAnswer(42) + }, errorMessageSubstring: "wrong answer!") + } - access(all) struct Foo { - access(self) let answer: UInt8 + access(all) + struct Foo { + access(self) let answer: UInt8 - init(answer: UInt8) { - self.answer = answer - } + init(answer: UInt8) { + self.answer = answer + } - access(all) fun correctAnswer(_ input: UInt8): Bool { - if self.answer != input { - panic("wrong answer!") - } - return true - } - } - ` + access(all) + fun correctAnswer(_ input: UInt8): Bool { + if self.answer != input { + panic("wrong answer!") + } + return true + } + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1923,30 +2034,33 @@ func TestTestExpectFailure(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test() { - let foo = Foo(answer: 42) - Test.expectFailure(fun(): Void { - foo.correctAnswer(43) - }, errorMessageSubstring: "wrong answer!") - } + access(all) + fun test() { + let foo = Foo(answer: 42) + Test.expectFailure(fun(): Void { + foo.correctAnswer(43) + }, errorMessageSubstring: "wrong answer!") + } - access(all) struct Foo { - access(self) let answer: UInt8 + access(all) + struct Foo { + access(self) let answer: UInt8 - init(answer: UInt8) { - self.answer = answer - } + init(answer: UInt8) { + self.answer = answer + } - access(all) fun correctAnswer(_ input: UInt8): Bool { - if self.answer != input { - panic("wrong answer!") - } - return true - } - } - ` + access(all) + fun correctAnswer(_ input: UInt8): Bool { + if self.answer != input { + panic("wrong answer!") + } + return true + } + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -1959,30 +2073,33 @@ func TestTestExpectFailure(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test() { - let foo = Foo(answer: 42) - Test.expectFailure(fun(): Void { - foo.correctAnswer(43) - }, errorMessageSubstring: "what is wrong?") - } + access(all) + fun test() { + let foo = Foo(answer: 42) + Test.expectFailure(fun(): Void { + foo.correctAnswer(43) + }, errorMessageSubstring: "what is wrong?") + } - access(all) struct Foo { - access(self) let answer: UInt8 + access(all) + struct Foo { + access(self) let answer: UInt8 - init(answer: UInt8) { - self.answer = answer - } + init(answer: UInt8) { + self.answer = answer + } - access(all) fun correctAnswer(_ input: UInt8): Bool { - if self.answer != input { - panic("wrong answer!") - } - return true - } - } - ` + access(all) + fun correctAnswer(_ input: UInt8): Bool { + if self.answer != input { + panic("wrong answer!") + } + return true + } + } + ` inter, err := newTestContractInterpreter(t, script) require.NoError(t, err) @@ -2000,31 +2117,34 @@ func TestTestExpectFailure(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test() { - let foo = Foo(answer: 42) - Test.expectFailure(fun(answer: UInt64): Foo { - foo.correctAnswer(42) - return foo - }, errorMessageSubstring: "wrong answer") - } + access(all) + fun test() { + let foo = Foo(answer: 42) + Test.expectFailure(fun(answer: UInt64): Foo { + foo.correctAnswer(42) + return foo + }, errorMessageSubstring: "wrong answer") + } - access(all) struct Foo { - access(self) let answer: UInt8 + access(all) + struct Foo { + access(self) let answer: UInt8 - init(answer: UInt8) { - self.answer = answer - } + init(answer: UInt8) { + self.answer = answer + } - access(all) fun correctAnswer(_ input: UInt8): Bool { - if self.answer != input { - panic("wrong answer!") - } - return true - } - } - ` + access(all) + fun correctAnswer(_ input: UInt8): Bool { + if self.answer != input { + panic("wrong answer!") + } + return true + } + } + ` _, err := newTestContractInterpreter(t, script) errs := checker.RequireCheckerErrors(t, err, 1) @@ -2035,30 +2155,33 @@ func TestTestExpectFailure(t *testing.T) { t.Parallel() script := ` - import Test + import Test - access(all) fun test() { - let foo = Foo(answer: 42) - Test.expectFailure(fun(): Void { - foo.correctAnswer(42) - }, errorMessageSubstring: ["wrong answer"]) - } + access(all) + fun test() { + let foo = Foo(answer: 42) + Test.expectFailure(fun(): Void { + foo.correctAnswer(42) + }, errorMessageSubstring: ["wrong answer"]) + } - access(all) struct Foo { - access(self) let answer: UInt8 + access(all) + struct Foo { + access(self) let answer: UInt8 - init(answer: UInt8) { - self.answer = answer - } + init(answer: UInt8) { + self.answer = answer + } - access(all) fun correctAnswer(_ input: UInt8): Bool { - if self.answer != input { - panic("wrong answer!") - } - return true - } - } - ` + access(all) + fun correctAnswer(_ input: UInt8): Bool { + if self.answer != input { + panic("wrong answer!") + } + return true + } + } + ` _, err := newTestContractInterpreter(t, script) errs := checker.RequireCheckerErrors(t, err, 1) @@ -2076,18 +2199,18 @@ func TestBlockchain(t *testing.T) { const script = ` import Test - access(all) fun test() { - let blockchain = Test.newEmulatorBlockchain() - let events = blockchain.events() + access(all) + fun test() { + let events = Test.events() Test.expect(events, Test.beEmpty()) } - ` + ` eventsInvoked := false testFramework := &mockedTestFramework{ - newEmulatorBackend: func() Blockchain { + emulatorBackend: func() stdlib.Blockchain { return &mockedBlockchain{ events: func(inter *interpreter.Interpreter, eventType interpreter.StaticType) interpreter.Value { eventsInvoked = true @@ -2121,25 +2244,22 @@ func TestBlockchain(t *testing.T) { access(all) struct Foo {} - access(all) + access(all) fun test() { - let blockchain = Test.newEmulatorBlockchain() - // 'Foo' is not an event-type. // But we just need to test the API, so it doesn't really matter. let typ = Type() - - let events = blockchain.eventsOfType(typ) + let events = Test.eventsOfType(typ) Test.expect(events, Test.beEmpty()) } - ` + ` eventsInvoked := false testFramework := &mockedTestFramework{ - newEmulatorBackend: func() Blockchain { + emulatorBackend: func() stdlib.Blockchain { return &mockedBlockchain{ events: func(inter *interpreter.Interpreter, eventType interpreter.StaticType) interpreter.Value { eventsInvoked = true @@ -2177,15 +2297,14 @@ func TestBlockchain(t *testing.T) { access(all) fun test() { - let blockchain = Test.newEmulatorBlockchain() - blockchain.reset(to: 5) + Test.reset(to: 5) } - ` + ` resetInvoked := false testFramework := &mockedTestFramework{ - newEmulatorBackend: func() Blockchain { + emulatorBackend: func() stdlib.Blockchain { return &mockedBlockchain{ reset: func(height uint64) { resetInvoked = true @@ -2212,15 +2331,14 @@ func TestBlockchain(t *testing.T) { access(all) fun test() { - let blockchain = Test.newEmulatorBlockchain() - blockchain.reset(to: 5.5) + Test.reset(to: 5.5) } - ` + ` resetInvoked := false testFramework := &mockedTestFramework{ - newEmulatorBackend: func() Blockchain { + emulatorBackend: func() stdlib.Blockchain { return &mockedBlockchain{ reset: func(height uint64) { resetInvoked = true @@ -2243,18 +2361,17 @@ func TestBlockchain(t *testing.T) { access(all) fun testMoveForward() { - let blockchain = Test.newEmulatorBlockchain() // timeDelta is the representation of 35 days, // in the form of seconds. let timeDelta = Fix64(35 * 24 * 60 * 60) - blockchain.moveTime(by: timeDelta) + Test.moveTime(by: timeDelta) } - ` + ` moveTimeInvoked := false testFramework := &mockedTestFramework{ - newEmulatorBackend: func() Blockchain { + emulatorBackend: func() stdlib.Blockchain { return &mockedBlockchain{ moveTime: func(timeDelta int64) { moveTimeInvoked = true @@ -2281,18 +2398,17 @@ func TestBlockchain(t *testing.T) { access(all) fun testMoveBackward() { - let blockchain = Test.newEmulatorBlockchain() // timeDelta is the representation of 35 days, // in the form of seconds. let timeDelta = Fix64(35 * 24 * 60 * 60) * -1.0 - blockchain.moveTime(by: timeDelta) + Test.moveTime(by: timeDelta) } - ` + ` moveTimeInvoked := false testFramework := &mockedTestFramework{ - newEmulatorBackend: func() Blockchain { + emulatorBackend: func() stdlib.Blockchain { return &mockedBlockchain{ moveTime: func(timeDelta int64) { moveTimeInvoked = true @@ -2319,15 +2435,14 @@ func TestBlockchain(t *testing.T) { access(all) fun testMoveTime() { - let blockchain = Test.newEmulatorBlockchain() - blockchain.moveTime(by: 3000) + Test.moveTime(by: 3000) } - ` + ` moveTimeInvoked := false testFramework := &mockedTestFramework{ - newEmulatorBackend: func() Blockchain { + emulatorBackend: func() stdlib.Blockchain { return &mockedBlockchain{ moveTime: func(timeDelta int64) { moveTimeInvoked = true @@ -2342,7 +2457,7 @@ func TestBlockchain(t *testing.T) { assert.False(t, moveTimeInvoked) }) - t.Run("newEmulatorBackend", func(t *testing.T) { + t.Run("createSnapshot", func(t *testing.T) { t.Parallel() const script = ` @@ -2350,45 +2465,14 @@ func TestBlockchain(t *testing.T) { access(all) fun test() { - let blockchain = Test.newEmulatorBlockchain() - Test.assertEqual(Type(), blockchain.getType()) - } - ` - - newEmulatorBackendInvoked := false - - testFramework := &mockedTestFramework{ - newEmulatorBackend: func() Blockchain { - newEmulatorBackendInvoked = true - return &mockedBlockchain{} - }, - } - - inter, err := newTestContractInterpreterWithTestFramework(t, script, testFramework) - require.NoError(t, err) - - _, err = inter.Invoke("test") - require.NoError(t, err) - - assert.True(t, newEmulatorBackendInvoked) - }) - - t.Run("createSnapshot", func(t *testing.T) { - t.Parallel() - - const script = ` - import Test - - access(all) fun test() { - let blockchain = Test.newEmulatorBlockchain() - blockchain.createSnapshot(name: "adminCreated") + Test.createSnapshot(name: "adminCreated") } - ` + ` createSnapshotInvoked := false testFramework := &mockedTestFramework{ - newEmulatorBackend: func() Blockchain { + emulatorBackend: func() stdlib.Blockchain { return &mockedBlockchain{ createSnapshot: func(name string) error { createSnapshotInvoked = true @@ -2415,16 +2499,16 @@ func TestBlockchain(t *testing.T) { const script = ` import Test - access(all) fun test() { - let blockchain = Test.newEmulatorBlockchain() - blockchain.createSnapshot(name: "adminCreated") + access(all) + fun test() { + Test.createSnapshot(name: "adminCreated") } - ` + ` createSnapshotInvoked := false testFramework := &mockedTestFramework{ - newEmulatorBackend: func() Blockchain { + emulatorBackend: func() stdlib.Blockchain { return &mockedBlockchain{ createSnapshot: func(name string) error { createSnapshotInvoked = true @@ -2451,17 +2535,17 @@ func TestBlockchain(t *testing.T) { const script = ` import Test - access(all) fun test() { - let blockchain = Test.newEmulatorBlockchain() - blockchain.createSnapshot(name: "adminCreated") - blockchain.loadSnapshot(name: "adminCreated") + access(all) + fun test() { + Test.createSnapshot(name: "adminCreated") + Test.loadSnapshot(name: "adminCreated") } - ` + ` loadSnapshotInvoked := false testFramework := &mockedTestFramework{ - newEmulatorBackend: func() Blockchain { + emulatorBackend: func() stdlib.Blockchain { return &mockedBlockchain{ createSnapshot: func(name string) error { assert.Equal(t, "adminCreated", name) @@ -2493,17 +2577,17 @@ func TestBlockchain(t *testing.T) { const script = ` import Test - access(all) fun test() { - let blockchain = Test.newEmulatorBlockchain() - blockchain.createSnapshot(name: "adminCreated") - blockchain.loadSnapshot(name: "contractDeployed") + access(all) + fun test() { + Test.createSnapshot(name: "adminCreated") + Test.loadSnapshot(name: "contractDeployed") } - ` + ` loadSnapshotInvoked := false testFramework := &mockedTestFramework{ - newEmulatorBackend: func() Blockchain { + emulatorBackend: func() stdlib.Blockchain { return &mockedBlockchain{ createSnapshot: func(name string) error { assert.Equal(t, "adminCreated", name) @@ -2529,6 +2613,193 @@ func TestBlockchain(t *testing.T) { assert.True(t, loadSnapshotInvoked) }) + t.Run("deployContract", func(t *testing.T) { + t.Parallel() + + const script = ` + import Test + + access(all) + fun test() { + let err = Test.deployContract( + name: "FooContract", + path: "./contracts/FooContract.cdc", + arguments: ["Hey, there!"] + ) + + Test.expect(err, Test.beNil()) + } + ` + + deployContractInvoked := false + + testFramework := &mockedTestFramework{ + emulatorBackend: func() stdlib.Blockchain { + return &mockedBlockchain{ + deployContract: func( + inter *interpreter.Interpreter, + name string, + path string, + arguments []interpreter.Value, + ) error { + deployContractInvoked = true + assert.Equal(t, "FooContract", name) + assert.Equal(t, "./contracts/FooContract.cdc", path) + assert.Equal(t, 1, len(arguments)) + argument := arguments[0].(*interpreter.StringValue) + assert.Equal(t, "Hey, there!", argument.Str) + + return nil + }, + } + }, + } + + inter, err := newTestContractInterpreterWithTestFramework(t, script, testFramework) + require.NoError(t, err) + + _, err = inter.Invoke("test") + require.NoError(t, err) + + assert.True(t, deployContractInvoked) + }) + + t.Run("deployContract with failure", func(t *testing.T) { + t.Parallel() + + const script = ` + import Test + + access(all) + fun test() { + let err = Test.deployContract( + name: "FooContract", + path: "./contracts/FooContract.cdc", + arguments: ["Hey, there!"] + ) + + Test.assertEqual( + "failed to deploy contract: FooContract", + err!.message + ) + } + ` + + deployContractInvoked := false + + testFramework := &mockedTestFramework{ + emulatorBackend: func() stdlib.Blockchain { + return &mockedBlockchain{ + deployContract: func( + inter *interpreter.Interpreter, + name string, + path string, + arguments []interpreter.Value, + ) error { + deployContractInvoked = true + + return fmt.Errorf("failed to deploy contract: %s", name) + }, + } + }, + } + + inter, err := newTestContractInterpreterWithTestFramework(t, script, testFramework) + require.NoError(t, err) + + _, err = inter.Invoke("test") + require.NoError(t, err) + + assert.True(t, deployContractInvoked) + }) + + t.Run("getAccount", func(t *testing.T) { + t.Parallel() + + const script = ` + import Test + + access(all) + fun test() { + let account = Test.getAccount(0x0000000000000009) + Test.assertEqual(0x0000000000000009 as Address, account.address) + } + ` + + getAccountInvoked := false + + testFramework := &mockedTestFramework{ + emulatorBackend: func() stdlib.Blockchain { + return &mockedBlockchain{ + getAccount: func(address interpreter.AddressValue) (*stdlib.Account, error) { + getAccountInvoked = true + assert.Equal(t, "0000000000000009", address.Hex()) + addr := common.Address(address) + + return &stdlib.Account{ + Address: addr, + PublicKey: &stdlib.PublicKey{ + PublicKey: []byte{1, 2, 3}, + SignAlgo: sema.SignatureAlgorithmECDSA_P256, + }, + }, nil + }, + stdlibHandler: func() stdlib.StandardLibraryHandler { + return runtime.NewBaseInterpreterEnvironment(runtime.Config{}) + }, + } + }, + } + + inter, err := newTestContractInterpreterWithTestFramework(t, script, testFramework) + require.NoError(t, err) + + _, err = inter.Invoke("test") + require.NoError(t, err) + + assert.True(t, getAccountInvoked) + }) + + t.Run("getAccount with failure", func(t *testing.T) { + t.Parallel() + + const script = ` + import Test + + access(all) + fun test() { + let account = Test.getAccount(0x0000000000000009) + } + ` + + getAccountInvoked := false + + testFramework := &mockedTestFramework{ + emulatorBackend: func() stdlib.Blockchain { + return &mockedBlockchain{ + getAccount: func(address interpreter.AddressValue) (*stdlib.Account, error) { + getAccountInvoked = true + assert.Equal(t, "0000000000000009", address.Hex()) + + return nil, fmt.Errorf("failed to retrieve account with address: %s", address) + }, + stdlibHandler: func() stdlib.StandardLibraryHandler { + return runtime.NewBaseInterpreterEnvironment(runtime.Config{}) + }, + } + }, + } + + inter, err := newTestContractInterpreterWithTestFramework(t, script, testFramework) + require.NoError(t, err) + + _, err = inter.Invoke("test") + require.Error(t, err) + assert.ErrorContains(t, err, "account with address: 0x0000000000000009 was not found") + + assert.True(t, getAccountInvoked) + }) + // TODO: Add more tests for the remaining functions. } @@ -2542,27 +2813,26 @@ func TestBlockchainAccount(t *testing.T) { const script = ` import Test - access(all) fun test() { - let blockchain = Test.newEmulatorBlockchain() - let account = blockchain.createAccount() + access(all) + fun test() { + let account = Test.createAccount() assert(account.address == 0x0100000000000000) } - ` + ` testFramework := &mockedTestFramework{ - newEmulatorBackend: func() Blockchain { + emulatorBackend: func() stdlib.Blockchain { return &mockedBlockchain{ - createAccount: func() (*Account, error) { - return &Account{ - PublicKey: &PublicKey{ + createAccount: func() (*stdlib.Account, error) { + return &stdlib.Account{ + PublicKey: &stdlib.PublicKey{ PublicKey: []byte{1, 2, 3}, SignAlgo: sema.SignatureAlgorithmECDSA_P256, }, Address: common.Address{1}, }, nil }, - - stdlibHandler: func() StandardLibraryHandler { + stdlibHandler: func() stdlib.StandardLibraryHandler { return nil }, } @@ -2578,18 +2848,18 @@ func TestBlockchainAccount(t *testing.T) { } type mockedTestFramework struct { - newEmulatorBackend func() Blockchain - readFile func(s string) (string, error) + emulatorBackend func() stdlib.Blockchain + readFile func(s string) (string, error) } -var _ TestFramework = &mockedTestFramework{} +var _ stdlib.TestFramework = &mockedTestFramework{} -func (m mockedTestFramework) NewEmulatorBackend() Blockchain { - if m.newEmulatorBackend == nil { +func (m mockedTestFramework) EmulatorBackend() stdlib.Blockchain { + if m.emulatorBackend == nil { panic("'NewEmulatorBackend' is not implemented") } - return m.newEmulatorBackend() + return m.emulatorBackend() } func (m mockedTestFramework) ReadFile(fileName string) (string, error) { @@ -2603,15 +2873,15 @@ func (m mockedTestFramework) ReadFile(fileName string) (string, error) { // mockedBlockchain is the implementation of `Blockchain` for testing purposes. type mockedBlockchain struct { runScript func(inter *interpreter.Interpreter, code string, arguments []interpreter.Value) - createAccount func() (*Account, error) - addTransaction func(inter *interpreter.Interpreter, code string, authorizers []common.Address, signers []*Account, arguments []interpreter.Value) error - executeTransaction func() *TransactionResult + createAccount func() (*stdlib.Account, error) + getAccount func(interpreter.AddressValue) (*stdlib.Account, error) + addTransaction func(inter *interpreter.Interpreter, code string, authorizers []common.Address, signers []*stdlib.Account, arguments []interpreter.Value) error + executeTransaction func() *stdlib.TransactionResult commitBlock func() error - deployContract func(inter *interpreter.Interpreter, name string, code string, account *Account, arguments []interpreter.Value) error - useConfiguration func(configuration *Configuration) - stdlibHandler func() StandardLibraryHandler + deployContract func(inter *interpreter.Interpreter, name string, path string, arguments []interpreter.Value) error + stdlibHandler func() stdlib.StandardLibraryHandler logs func() []string - serviceAccount func() (*Account, error) + serviceAccount func() (*stdlib.Account, error) events func(inter *interpreter.Interpreter, eventType interpreter.StaticType) interpreter.Value reset func(uint64) moveTime func(int64) @@ -2619,13 +2889,13 @@ type mockedBlockchain struct { loadSnapshot func(string) error } -var _ Blockchain = &mockedBlockchain{} +var _ stdlib.Blockchain = &mockedBlockchain{} func (m mockedBlockchain) RunScript( inter *interpreter.Interpreter, code string, arguments []interpreter.Value, -) *ScriptResult { +) *stdlib.ScriptResult { if m.runScript == nil { panic("'RunScript' is not implemented") } @@ -2633,7 +2903,7 @@ func (m mockedBlockchain) RunScript( return m.RunScript(inter, code, arguments) } -func (m mockedBlockchain) CreateAccount() (*Account, error) { +func (m mockedBlockchain) CreateAccount() (*stdlib.Account, error) { if m.createAccount == nil { panic("'CreateAccount' is not implemented") } @@ -2641,11 +2911,19 @@ func (m mockedBlockchain) CreateAccount() (*Account, error) { return m.createAccount() } +func (m mockedBlockchain) GetAccount(address interpreter.AddressValue) (*stdlib.Account, error) { + if m.getAccount == nil { + panic("'getAccount' is not implemented") + } + + return m.getAccount(address) +} + func (m mockedBlockchain) AddTransaction( inter *interpreter.Interpreter, code string, authorizers []common.Address, - signers []*Account, + signers []*stdlib.Account, arguments []interpreter.Value, ) error { if m.addTransaction == nil { @@ -2655,7 +2933,7 @@ func (m mockedBlockchain) AddTransaction( return m.addTransaction(inter, code, authorizers, signers, arguments) } -func (m mockedBlockchain) ExecuteNextTransaction() *TransactionResult { +func (m mockedBlockchain) ExecuteNextTransaction() *stdlib.TransactionResult { if m.executeTransaction == nil { panic("'ExecuteNextTransaction' is not implemented") } @@ -2674,26 +2952,17 @@ func (m mockedBlockchain) CommitBlock() error { func (m mockedBlockchain) DeployContract( inter *interpreter.Interpreter, name string, - code string, - account *Account, + path string, arguments []interpreter.Value, ) error { if m.deployContract == nil { panic("'DeployContract' is not implemented") } - return m.deployContract(inter, name, code, account, arguments) -} - -func (m mockedBlockchain) UseConfiguration(configuration *Configuration) { - if m.useConfiguration == nil { - panic("'UseConfiguration' is not implemented") - } - - m.useConfiguration(configuration) + return m.deployContract(inter, name, path, arguments) } -func (m mockedBlockchain) StandardLibraryHandler() StandardLibraryHandler { +func (m mockedBlockchain) StandardLibraryHandler() stdlib.StandardLibraryHandler { if m.stdlibHandler == nil { panic("'StandardLibraryHandler' is not implemented") } @@ -2709,7 +2978,7 @@ func (m mockedBlockchain) Logs() []string { return m.logs() } -func (m mockedBlockchain) ServiceAccount() (*Account, error) { +func (m mockedBlockchain) ServiceAccount() (*stdlib.Account, error) { if m.serviceAccount == nil { panic("'ServiceAccount' is not implemented") } diff --git a/runtime/stdlib/webassembly.gen.go b/runtime/stdlib/webassembly.gen.go index 3317c83c53..59f9073937 100644 --- a/runtime/stdlib/webassembly.gen.go +++ b/runtime/stdlib/webassembly.gen.go @@ -33,7 +33,7 @@ var WebAssemblyTypeCompileAndInstantiateFunctionType = &sema.FunctionType{ { Identifier: "bytes", TypeAnnotation: sema.NewTypeAnnotation(&sema.VariableSizedType{ - Type: UInt8Type, + Type: sema.UInt8Type, }), }, }, diff --git a/runtime/storage.go b/runtime/storage.go index 6a66a9fea5..a679657406 100644 --- a/runtime/storage.go +++ b/runtime/storage.go @@ -175,6 +175,17 @@ func (s *Storage) recordContractUpdate( s.contractUpdates.Set(key, contractValue) } +func (s *Storage) contractUpdateRecorded( + location common.AddressLocation, +) bool { + if s.contractUpdates == nil { + return false + } + + key := interpreter.NewStorageKey(s.memoryGauge, location.Address, location.Name) + return s.contractUpdates.Contains(key) +} + type ContractUpdate struct { ContractValue *interpreter.CompositeValue Key interpreter.StorageKey diff --git a/runtime/tests/checker/conditions_test.go b/runtime/tests/checker/conditions_test.go index 8960d89fc1..d00d0a94ae 100644 --- a/runtime/tests/checker/conditions_test.go +++ b/runtime/tests/checker/conditions_test.go @@ -1018,3 +1018,92 @@ func TestCheckRewrittenPostConditions(t *testing.T) { }) } + +func TestCheckBeforeConditions(t *testing.T) { + + t.Parallel() + + t.Run("function call", func(t *testing.T) { + + t.Parallel() + + _, err := ParseAndCheck(t, ` + fun impure(): Int { + return 0 + } + + fun test() { + post { + before(impure()) > 0 + } + } + `) + + errs := RequireCheckerErrors(t, err, 1) + + assert.IsType(t, &sema.PurityError{}, errs[0]) + }) + + t.Run("view function call", func(t *testing.T) { + + t.Parallel() + + _, err := ParseAndCheck(t, ` + view fun pure(): Int { + return 0 + } + + fun test() { + post { + before(pure()) > 0 + } + } + `) + + require.NoError(t, err) + }) + + t.Run("nested function call", func(t *testing.T) { + + t.Parallel() + + _, err := ParseAndCheck(t, ` + view fun pure(): Int { + return 0 + } + + fun impure(): Int { + return 0 + } + + fun test() { + post { + before(before(impure())) > pure() + } + } + `) + + errs := RequireCheckerErrors(t, err, 1) + + assert.IsType(t, &sema.PurityError{}, errs[0]) + }) + + t.Run("nested pure function call", func(t *testing.T) { + + t.Parallel() + + _, err := ParseAndCheck(t, ` + view fun pure(): Int { + return 0 + } + + fun test() { + post { + before(before(pure())) > 0 + } + } + `) + + require.NoError(t, err) + }) +} diff --git a/runtime/tests/checker/entitlements_test.go b/runtime/tests/checker/entitlements_test.go index b97813af75..727c0f613d 100644 --- a/runtime/tests/checker/entitlements_test.go +++ b/runtime/tests/checker/entitlements_test.go @@ -7222,3 +7222,221 @@ func TestCheckEntitlementErrorReporting(t *testing.T) { ) }) } + +func TestCheckEntitlementOptionalChaining(t *testing.T) { + + t.Parallel() + + t.Run("optional chain function call", func(t *testing.T) { + t.Parallel() + _, err := ParseAndCheck(t, ` + entitlement X + + struct S { + access(X) fun foo() {} + } + + fun bar(r: &S?) { + r?.foo() + } + `) + + errs := RequireCheckerErrors(t, err, 1) + var invalidAccessErr *sema.InvalidAccessError + require.ErrorAs(t, errs[0], &invalidAccessErr) + }) + + t.Run("optional chain field access", func(t *testing.T) { + t.Parallel() + _, err := ParseAndCheck(t, ` + entitlement X + entitlement Y + + struct S { + access(X, Y) let foo: Int + init() { + self.foo = 0 + } + } + + fun bar(r: auth(X) &S?) { + r?.foo + } + `) + + errs := RequireCheckerErrors(t, err, 1) + var invalidAccessErr *sema.InvalidAccessError + require.ErrorAs(t, errs[0], &invalidAccessErr) + }) + + t.Run("optional chain non reference", func(t *testing.T) { + t.Parallel() + _, err := ParseAndCheck(t, ` + entitlement X + entitlement Y + + struct S { + access(X, Y) let foo: Int + init() { + self.foo = 0 + } + } + + fun bar(r: S?) { + r?.foo + } + `) + + require.NoError(t, err) + }) + + t.Run("optional chain mapping", func(t *testing.T) { + t.Parallel() + _, err := ParseAndCheck(t, ` + entitlement X + entitlement Y + + entitlement mapping E { + X -> Y + } + + struct S { + access(E) let foo: auth(E) &Int + init() { + self.foo = &0 as auth(Y) &Int + } + } + + fun bar(r: (auth(X) &S)?): (auth(Y) &Int)? { + return r?.foo + } + `) + + require.NoError(t, err) + }) +} + +func TestCheckEntitlementMissingInMap(t *testing.T) { + + t.Parallel() + + t.Run("missing type", func(t *testing.T) { + + t.Parallel() + + _, err := ParseAndCheck(t, ` + access(all) entitlement X + access(all) entitlement mapping M { + X -> X + NonExistingEntitlement -> X + } + access(all) struct S { + access(M) var foo: auth(M) &Int + init() { + self.foo = &3 as auth(X) &Int + var selfRef = &self as auth(X) &S + selfRef.foo + } + } + `) + + errors := RequireCheckerErrors(t, err, 2) + require.IsType(t, &sema.NotDeclaredError{}, errors[0]) + require.IsType(t, &sema.InvalidNonEntitlementTypeInMapError{}, errors[1]) + }) + + t.Run("non entitlement type", func(t *testing.T) { + + t.Parallel() + + _, err := ParseAndCheck(t, ` + access(all) entitlement X + access(all) entitlement mapping M { + X -> X + Int -> X + } + access(all) struct S { + access(M) var foo: auth(M) &Int + init() { + self.foo = &3 as auth(X) &Int + var selfRef = &self as auth(X) &S + selfRef.foo + } + } + `) + + errors := RequireCheckerErrors(t, err, 1) + require.IsType(t, &sema.InvalidNonEntitlementTypeInMapError{}, errors[0]) + }) +} + +func TestInterpretMappingEscalation(t *testing.T) { + + t.Parallel() + + t.Run("escalate", func(t *testing.T) { + t.Parallel() + + _, err := ParseAndCheck(t, ` + entitlement X + entitlement Y + entitlement mapping M { + X -> Insert + Y -> Remove + } + struct S { + access(M) var member: auth(M) &[Int]? + init() { + self.member = nil; + } + access(all) fun grantRemovePrivileges(param: auth(Insert) &[Int]): Void{ + var selfRef = &self as auth(X) &S; + selfRef.member = param; + } + } + fun main(): Void { + var arr: [Int] = [123]; + var arrRef = &arr as auth(Insert) &[Int]; + let s = S() + s.grantRemovePrivileges(param: arrRef); + s.member?.removeLast() + } + `) + + errors := RequireCheckerErrors(t, err, 1) + require.IsType(t, &sema.TypeMismatchError{}, errors[0]) + }) + + t.Run("field assign", func(t *testing.T) { + t.Parallel() + + _, err := ParseAndCheck(t, ` + entitlement X + entitlement Y + entitlement mapping M { + X -> Insert + Y -> Remove + } + struct S { + access(M) var member: auth(M) &[Int]? + init() { + self.member = nil; + } + access(all) fun grantRemovePrivileges(sRef: auth(X) &S, param: auth(Insert) &[Int]): Void{ + sRef.member = param; + } + } + fun main(): Void { + var arr: [Int] = [123]; + var arrRef = &arr as auth(Insert) &[Int]; + let s = S() + s.grantRemovePrivileges(sRef: &s as auth(X) &S, param: arrRef); + s.member?.removeLast() + } + `) + + errors := RequireCheckerErrors(t, err, 1) + require.IsType(t, &sema.TypeMismatchError{}, errors[0]) + }) + +} diff --git a/runtime/tests/checker/function_test.go b/runtime/tests/checker/function_test.go index 1a2428748b..5e1facb8cb 100644 --- a/runtime/tests/checker/function_test.go +++ b/runtime/tests/checker/function_test.go @@ -24,6 +24,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/onflow/cadence/runtime/ast" + "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/parser" "github.com/onflow/cadence/runtime/sema" ) @@ -429,20 +431,123 @@ func TestCheckNativeFunctionDeclaration(t *testing.T) { t.Parallel() - _, err := ParseAndCheckWithOptions(t, - ` - native fun test() {} - `, - ParseAndCheckOptions{ - ParseOptions: parser.Config{ - NativeModifierEnabled: true, + t.Run("disabled", func(t *testing.T) { + + t.Parallel() + + _, err := ParseAndCheckWithOptions(t, + ` + native fun test(): Int {} + `, + ParseAndCheckOptions{ + ParseOptions: parser.Config{ + NativeModifierEnabled: true, + }, + Config: &sema.Config{ + AllowNativeDeclarations: false, + }, }, - }, - ) + ) - errs := RequireCheckerErrors(t, err, 1) + errs := RequireCheckerErrors(t, err, 1) + + assert.IsType(t, &sema.InvalidNativeModifierError{}, errs[0]) + }) + + t.Run("enabled, valid", func(t *testing.T) { + + t.Parallel() + + _, err := ParseAndCheckWithOptions(t, + ` + native fun test(): Int {} + `, + ParseAndCheckOptions{ + ParseOptions: parser.Config{ + NativeModifierEnabled: true, + }, + Config: &sema.Config{ + AllowNativeDeclarations: true, + }, + }, + ) + + require.NoError(t, err) + }) + + t.Run("enabled, invalid", func(t *testing.T) { - assert.IsType(t, &sema.InvalidNativeModifierError{}, errs[0]) + t.Parallel() + + _, err := ParseAndCheckWithOptions(t, + ` + native fun test(): Int { + return 1 + } + `, + ParseAndCheckOptions{ + ParseOptions: parser.Config{ + NativeModifierEnabled: true, + }, + Config: &sema.Config{ + AllowNativeDeclarations: true, + }, + }, + ) + + errs := RequireCheckerErrors(t, err, 1) + + assert.IsType(t, &sema.NativeFunctionWithImplementationError{}, errs[0]) + }) + + t.Run("enabled, composite", func(t *testing.T) { + + t.Parallel() + + checker, err := ParseAndCheckWithOptions(t, + ` + struct S { + native fun test(foo: String): Int {} + } + `, + ParseAndCheckOptions{ + ParseOptions: parser.Config{ + NativeModifierEnabled: true, + }, + Config: &sema.Config{ + AllowNativeDeclarations: true, + }, + }, + ) + require.NoError(t, err) + + sType := RequireGlobalType(t, checker.Elaboration, "S") + require.NotNil(t, sType) + + const testFunctionIdentifier = "test" + testMemberResolver, ok := sType.GetMembers()[testFunctionIdentifier] + require.True(t, ok) + + assert.Equal(t, + common.DeclarationKindFunction, + testMemberResolver.Kind, + ) + + member := testMemberResolver.Resolve(nil, testFunctionIdentifier, ast.EmptyRange, nil) + + assert.Equal(t, + sema.NewTypeAnnotation(&sema.FunctionType{ + Parameters: []sema.Parameter{ + { + Identifier: "foo", + TypeAnnotation: sema.NewTypeAnnotation(sema.StringType), + }, + }, + ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.IntType), + }), + member.TypeAnnotation, + ) + }) } func TestCheckResultVariable(t *testing.T) { diff --git a/runtime/tests/checker/resources_test.go b/runtime/tests/checker/resources_test.go index f814147eee..db9726e67a 100644 --- a/runtime/tests/checker/resources_test.go +++ b/runtime/tests/checker/resources_test.go @@ -5673,9 +5673,10 @@ func TestCheckInvalidationInPostConditionBefore(t *testing.T) { } `) - errs := RequireCheckerErrors(t, err, 1) + errs := RequireCheckerErrors(t, err, 2) - assert.IsType(t, &sema.ResourceUseAfterInvalidationError{}, errs[0]) + assert.IsType(t, &sema.PurityError{}, errs[0]) + assert.IsType(t, &sema.ResourceUseAfterInvalidationError{}, errs[1]) } func TestCheckInvalidationInPostCondition(t *testing.T) { diff --git a/runtime/tests/checker/string_test.go b/runtime/tests/checker/string_test.go index 2ce9fc681b..5d94c0c077 100644 --- a/runtime/tests/checker/string_test.go +++ b/runtime/tests/checker/string_test.go @@ -408,3 +408,46 @@ func TestCheckStringJoinTypeMissingArgumentLabelSeparator(t *testing.T) { assert.IsType(t, &sema.MissingArgumentLabelError{}, errs[0]) } + +func TestCheckStringSplit(t *testing.T) { + + t.Parallel() + + checker, err := ParseAndCheck(t, ` + let s = "👪.❤️.Abc".split(separator: ".") + `) + require.NoError(t, err) + + assert.Equal(t, + &sema.VariableSizedType{ + Type: sema.StringType, + }, + RequireGlobalValue(t, checker.Elaboration, "s"), + ) +} + +func TestCheckStringSplitTypeMismatchSeparator(t *testing.T) { + + t.Parallel() + + _, err := ParseAndCheck(t, ` + let s = "Abc:1".split(separator: 1234) + `) + + errs := RequireCheckerErrors(t, err, 1) + + assert.IsType(t, &sema.TypeMismatchError{}, errs[0]) +} + +func TestCheckStringSplitTypeMissingArgumentLabelSeparator(t *testing.T) { + + t.Parallel() + + _, err := ParseAndCheck(t, ` + let s = "👪Abc".split("/") + `) + + errs := RequireCheckerErrors(t, err, 1) + + assert.IsType(t, &sema.MissingArgumentLabelError{}, errs[0]) +} diff --git a/runtime/tests/checker/utils.go b/runtime/tests/checker/utils.go index a5488f5bf1..7d12072002 100644 --- a/runtime/tests/checker/utils.go +++ b/runtime/tests/checker/utils.go @@ -24,7 +24,8 @@ import ( "sync" "testing" - "github.com/go-test/deep" + gopretty "github.com/kr/pretty" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -35,10 +36,6 @@ import ( "github.com/onflow/cadence/runtime/tests/utils" ) -func init() { - deep.MaxDepth = 20 -} - func ParseAndCheck(t testing.TB, code string) (*sema.Checker, error) { return ParseAndCheckWithOptions(t, code, ParseAndCheckOptions{ // allow attachments is on by default for testing purposes @@ -159,9 +156,9 @@ func ParseAndCheckWithOptionsAndMemoryMetering( err = firstResult.err for otherResult := range results { - diff := deep.Equal(err, otherResult.err) - if diff != nil { - t.Error(diff) + diff := gopretty.Diff(err, otherResult.err) + if len(diff) > 0 { + t.Error(strings.Join(diff, "\n")) } } diff --git a/runtime/tests/interpreter/account_test.go b/runtime/tests/interpreter/account_test.go index e0f83103be..142eab408d 100644 --- a/runtime/tests/interpreter/account_test.go +++ b/runtime/tests/interpreter/account_test.go @@ -116,6 +116,7 @@ type testAccountHandler struct { ) updateAccountContractCode func(location common.AddressLocation, code []byte) error recordContractUpdate func(location common.AddressLocation, value *interpreter.CompositeValue) + contractUpdateRecorded func(location common.AddressLocation) bool interpretContract func( location common.AddressLocation, program *interpreter.Program, @@ -317,6 +318,13 @@ func (t *testAccountHandler) RecordContractUpdate(location common.AddressLocatio t.recordContractUpdate(location, value) } +func (t *testAccountHandler) ContractUpdateRecorded(location common.AddressLocation) bool { + if t.contractUpdateRecorded == nil { + panic(errors.NewUnexpectedError("unexpected call to ContractUpdateRecorded")) + } + return t.contractUpdateRecorded(location) +} + func (t *testAccountHandler) InterpretContract( location common.AddressLocation, program *interpreter.Program, diff --git a/runtime/tests/interpreter/attachments_test.go b/runtime/tests/interpreter/attachments_test.go index 27d1b89818..6d6d4ccc92 100644 --- a/runtime/tests/interpreter/attachments_test.go +++ b/runtime/tests/interpreter/attachments_test.go @@ -2237,6 +2237,40 @@ func TestInterpretMutationDuringForEachAttachment(t *testing.T) { AssertValuesEqual(t, inter, interpreter.NewUnmeteredIntValueFromInt64(3), value) }) + + t.Run("callback", func(t *testing.T) { + + t.Parallel() + + inter := parseCheckAndInterpret(t, ` + access(all) resource R { + let foo: Int + init() { + self.foo = 9 + } + } + access(all) attachment A for R { + access(all) fun touchBase(): Int { + var foo = base.foo + return foo + } + } + access(all) fun main(): Int { + var r <- attach A() to <- create R() + var id: Int = 0 + r.forEachAttachment(fun(a: &AnyResourceAttachment) { + id = (a as! &A).touchBase() + }); + destroy r + return id + } + `) + + value, err := inter.Invoke("main") + require.NoError(t, err) + + AssertValuesEqual(t, inter, interpreter.NewUnmeteredIntValueFromInt64(9), value) + }) } func TestInterpretBuiltinCompositeAttachment(t *testing.T) { diff --git a/runtime/tests/interpreter/interpreter_test.go b/runtime/tests/interpreter/interpreter_test.go index 6f2bb2e5d3..4c83de0a4c 100644 --- a/runtime/tests/interpreter/interpreter_test.go +++ b/runtime/tests/interpreter/interpreter_test.go @@ -26,6 +26,7 @@ import ( "github.com/onflow/atree" + "github.com/onflow/cadence/runtime" "github.com/onflow/cadence/runtime/activations" "github.com/stretchr/testify/assert" @@ -70,6 +71,65 @@ func parseCheckAndInterpretWithOptions( return parseCheckAndInterpretWithOptionsAndMemoryMetering(t, code, options, nil) } +func parseCheckAndInterpretWithLogs( + tb testing.TB, + code string, +) ( + inter *interpreter.Interpreter, + getLogs func() []string, + err error, +) { + var logs []string + + logFunction := stdlib.NewStandardLibraryFunction( + "log", + &sema.FunctionType{ + Parameters: []sema.Parameter{ + { + Label: sema.ArgumentLabelNotRequired, + Identifier: "value", + TypeAnnotation: sema.NewTypeAnnotation(sema.AnyStructType), + }, + }, + ReturnTypeAnnotation: sema.NewTypeAnnotation( + sema.VoidType, + ), + }, + ``, + func(invocation interpreter.Invocation) interpreter.Value { + message := invocation.Arguments[0].String() + logs = append(logs, message) + return interpreter.Void + }, + ) + + baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) + baseValueActivation.DeclareValue(logFunction) + + baseActivation := activations.NewActivation(nil, interpreter.BaseActivation) + interpreter.Declare(baseActivation, logFunction) + + result, err := parseCheckAndInterpretWithOptions( + tb, + code, + ParseCheckAndInterpretOptions{ + Config: &interpreter.Config{ + BaseActivation: baseActivation, + }, + CheckerConfig: &sema.Config{ + BaseValueActivation: baseValueActivation, + }, + HandleCheckerError: nil, + }, + ) + + getLogs = func() []string { + return logs + } + + return result, getLogs, err +} + func parseCheckAndInterpretWithMemoryMetering( t testing.TB, code string, @@ -8506,48 +8566,65 @@ func TestInterpretContractAccountFieldUse(t *testing.T) { access(all) let address2 = Test.test() ` - addressValue := interpreter.AddressValue(common.MustBytesToAddress([]byte{0x1})) + t.Run("with custom handler", func(t *testing.T) { + addressValue := interpreter.AddressValue(common.MustBytesToAddress([]byte{0x1})) - inter, err := parseCheckAndInterpretWithOptions(t, code, - ParseCheckAndInterpretOptions{ - Config: &interpreter.Config{ - ContractValueHandler: makeContractValueHandler(nil, nil, nil), - InjectedCompositeFieldsHandler: func( - inter *interpreter.Interpreter, - _ common.Location, - _ string, - _ common.CompositeKind, - ) map[string]interpreter.Value { - - accountRef := stdlib.NewAccountReferenceValue( - nil, - nil, - addressValue, - interpreter.FullyEntitledAccountAccess, - ) - - return map[string]interpreter.Value{ - sema.ContractAccountFieldName: accountRef, - } + inter, err := parseCheckAndInterpretWithOptions(t, + code, + ParseCheckAndInterpretOptions{ + Config: &interpreter.Config{ + ContractValueHandler: makeContractValueHandler(nil, nil, nil), + InjectedCompositeFieldsHandler: func( + inter *interpreter.Interpreter, + _ common.Location, + _ string, + _ common.CompositeKind, + ) map[string]interpreter.Value { + + accountRef := stdlib.NewAccountReferenceValue( + nil, + nil, + addressValue, + interpreter.FullyEntitledAccountAccess, + ) + + return map[string]interpreter.Value{ + sema.ContractAccountFieldName: accountRef, + } + }, }, }, - }, - ) - require.NoError(t, err) + ) + require.NoError(t, err) - AssertValuesEqual( - t, - inter, - addressValue, - inter.Globals.Get("address1").GetValue(), - ) + AssertValuesEqual( + t, + inter, + addressValue, + inter.Globals.Get("address1").GetValue(), + ) - AssertValuesEqual( - t, - inter, - addressValue, - inter.Globals.Get("address2").GetValue(), - ) + AssertValuesEqual( + t, + inter, + addressValue, + inter.Globals.Get("address2").GetValue(), + ) + }) + + t.Run("with default handler", func(t *testing.T) { + env := runtime.NewBaseInterpreterEnvironment(runtime.Config{}) + _, err := parseCheckAndInterpretWithOptions(t, code, + ParseCheckAndInterpretOptions{ + Config: &interpreter.Config{ + ContractValueHandler: makeContractValueHandler(nil, nil, nil), + InjectedCompositeFieldsHandler: env.InterpreterConfig.InjectedCompositeFieldsHandler, + }, + }, + ) + require.Error(t, err) + assert.ErrorContains(t, err, "error: member `account` is used before it has been initialized") + }) } func TestInterpretConformToImportedInterface(t *testing.T) { @@ -9502,88 +9579,49 @@ func TestInterpretNestedDestroy(t *testing.T) { t.Parallel() - var logs []string - - logFunction := stdlib.NewStandardLibraryFunction( - "log", - &sema.FunctionType{ - Parameters: []sema.Parameter{ - { - Label: sema.ArgumentLabelNotRequired, - Identifier: "value", - TypeAnnotation: sema.AnyStructTypeAnnotation, - }, - }, - ReturnTypeAnnotation: sema.VoidTypeAnnotation, - }, - ``, - func(invocation interpreter.Invocation) interpreter.Value { - message := invocation.Arguments[0].String() - logs = append(logs, message) - return interpreter.Void - }, - ) - - baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) - baseValueActivation.DeclareValue(logFunction) - - baseActivation := activations.NewActivation(nil, interpreter.BaseActivation) - interpreter.Declare(baseActivation, logFunction) - - inter, err := parseCheckAndInterpretWithOptions(t, - ` - resource B { - let id: Int + inter, getLogs, err := parseCheckAndInterpretWithLogs(t, ` + resource B { + let id: Int - init(_ id: Int){ - self.id = id - } + init(_ id: Int){ + self.id = id + } - destroy(){ - log("destroying B with id:") - log(self.id) - } + destroy(){ + log("destroying B with id:") + log(self.id) } + } - resource A { - let id: Int - let bs: @[B] + resource A { + let id: Int + let bs: @[B] - init(_ id: Int){ - self.id = id - self.bs <- [] - } + init(_ id: Int){ + self.id = id + self.bs <- [] + } - fun add(_ b: @B){ - self.bs.append(<-b) - } + fun add(_ b: @B){ + self.bs.append(<-b) + } - destroy() { - log("destroying A with id:") - log(self.id) - destroy self.bs - } + destroy() { + log("destroying A with id:") + log(self.id) + destroy self.bs } + } - fun test() { - let a <- create A(1) - a.add(<- create B(2)) - a.add(<- create B(3)) - a.add(<- create B(4)) + fun test() { + let a <- create A(1) + a.add(<- create B(2)) + a.add(<- create B(3)) + a.add(<- create B(4)) - destroy a - } - `, - ParseCheckAndInterpretOptions{ - Config: &interpreter.Config{ - BaseActivation: baseActivation, - }, - CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, - }, - HandleCheckerError: nil, - }, - ) + destroy a + } + `) require.NoError(t, err) value, err := inter.Invoke("test") @@ -9607,7 +9645,7 @@ func TestInterpretNestedDestroy(t *testing.T) { `"destroying B with id:"`, "4", }, - logs, + getLogs(), ) } @@ -11503,3 +11541,314 @@ func TestInterpretConditionsWrapperFunctionType(t *testing.T) { require.NoError(t, err) }) } + +func TestInterpretSwapInSameArray(t *testing.T) { + + t.Parallel() + + t.Run("resources, different indices", func(t *testing.T) { + t.Parallel() + + inter := parseCheckAndInterpret(t, ` + resource R { + let value: Int + + init(value: Int) { + self.value = value + } + } + + fun test(): [Int] { + let rs <- [ + <- create R(value: 0), + <- create R(value: 1), + <- create R(value: 2) + ] + + // We swap only '0' and '1' + rs[0] <-> rs[1] + + let values = [ + rs[0].value, + rs[1].value, + rs[2].value + ] + + destroy rs + + return values + } + `) + + value, err := inter.Invoke("test") + require.NoError(t, err) + + AssertValuesEqual( + t, + inter, + interpreter.NewArrayValue( + inter, + interpreter.EmptyLocationRange, + &interpreter.VariableSizedStaticType{ + Type: interpreter.PrimitiveStaticTypeInt, + }, + common.ZeroAddress, + interpreter.NewUnmeteredIntValueFromInt64(1), + interpreter.NewUnmeteredIntValueFromInt64(0), + interpreter.NewUnmeteredIntValueFromInt64(2), + ), + value, + ) + }) + + t.Run("resources, same indices", func(t *testing.T) { + + t.Parallel() + + inter := parseCheckAndInterpret(t, ` + resource R { + let value: Int + + init(value: Int) { + self.value = value + } + } + + fun test(): [Int] { + let rs <- [ + <- create R(value: 0), + <- create R(value: 1), + <- create R(value: 2) + ] + + // We swap only '1' + rs[1] <-> rs[1] + + let values = [ + rs[0].value, + rs[1].value, + rs[2].value + ] + + destroy rs + + return values + } + `) + + value, err := inter.Invoke("test") + require.NoError(t, err) + + AssertValuesEqual( + t, + inter, + interpreter.NewArrayValue( + inter, + interpreter.EmptyLocationRange, + &interpreter.VariableSizedStaticType{ + Type: interpreter.PrimitiveStaticTypeInt, + }, + common.ZeroAddress, + interpreter.NewUnmeteredIntValueFromInt64(0), + interpreter.NewUnmeteredIntValueFromInt64(1), + interpreter.NewUnmeteredIntValueFromInt64(2), + ), + value, + ) + }) + + t.Run("structs", func(t *testing.T) { + + t.Parallel() + + inter := parseCheckAndInterpret(t, ` + struct S { + let value: Int + + init(value: Int) { + self.value = value + } + } + + fun test(): [Int] { + let structs = [ + S(value: 0), + S(value: 1), + S(value: 2) + ] + + // We swap only '0' and '1' + structs[0] <-> structs[1] + + return [ + structs[0].value, + structs[1].value, + structs[2].value + ] + } + `) + + value, err := inter.Invoke("test") + require.NoError(t, err) + + AssertValuesEqual( + t, + inter, + interpreter.NewArrayValue( + inter, + interpreter.EmptyLocationRange, + &interpreter.VariableSizedStaticType{ + Type: interpreter.PrimitiveStaticTypeInt, + }, + common.ZeroAddress, + interpreter.NewUnmeteredIntValueFromInt64(1), + interpreter.NewUnmeteredIntValueFromInt64(0), + interpreter.NewUnmeteredIntValueFromInt64(2), + ), + value, + ) + }) +} + +func TestInterpretSwapDictionaryKeysWithSideEffects(t *testing.T) { + + t.Parallel() + + t.Run("simple", func(t *testing.T) { + t.Parallel() + + inter, getLogs, err := parseCheckAndInterpretWithLogs(t, ` + let xs: [{Int: String}] = [{2: "x"}, {3: "y"}] + + fun a(): Int { + log("a") + return 0 + } + + fun b(): Int { + log("b") + return 2 + } + + fun c(): Int { + log("c") + return 1 + } + + fun d(): Int { + log("d") + return 3 + } + + fun test() { + log(xs) + xs[a()][b()] <-> xs[c()][d()] + log(xs) + } + `) + require.NoError(t, err) + + _, err = inter.Invoke("test") + require.NoError(t, err) + + assert.Equal(t, + []string{ + `[{2: "x"}, {3: "y"}]`, + `"a"`, + `"b"`, + `"c"`, + `"d"`, + `[{2: "y"}, {3: "x"}]`, + }, + getLogs(), + ) + + }) + + t.Run("resources", func(t *testing.T) { + t.Parallel() + + inter, getLogs, err := parseCheckAndInterpretWithLogs(t, ` + resource Resource { + var value: Int + + init(_ value: Int) { + log( + "Creating resource with UUID " + .concat(self.uuid.toString()) + .concat(" and value ") + .concat(value.toString()) + ) + self.value = value + } + + destroy() { + log( + "Destroying resource with UUID " + .concat(self.uuid.toString()) + .concat(" and value ") + .concat(self.value.toString()) + ) + } + } + + resource ResourceLoser { + var dict: @{Int: Resource} + var toBeLost: @Resource + + init(_ victim: @Resource) { + self.dict <- {1: <- create Resource(2)} + + self.toBeLost <- victim + + // Magic happens during the swap below. + self.dict[1] <-> self.dict[self.shenanigans()] + } + + fun shenanigans(): Int { + var d <- create Resource(3) + + self.toBeLost <-> d + + // This takes advantage of the fact that self.dict[1] has been + // temporarily removed at the point of the swap when this gets called + // We take advantage of this window of opportunity to + // insert the "to-be-lost" resource in its place. The swap implementation + // will blindly overwrite it. + var old <- self.dict.insert(key: 1, <- d) + + // "old" will be nil here thanks to the removal done by the swap + // implementation. We have to destroy it to please sema checker. + destroy old + + return 1 + } + + destroy() { + destroy self.dict + destroy self.toBeLost + } + } + + fun test() { + destroy <- create ResourceLoser(<- create Resource(1)) + } + `) + require.NoError(t, err) + + _, err = inter.Invoke("test") + require.NoError(t, err) + + assert.Equal(t, + []string{ + `"Creating resource with UUID 1 and value 1"`, + `"Creating resource with UUID 3 and value 2"`, + `"Creating resource with UUID 4 and value 3"`, + `"Destroying resource with UUID 3 and value 2"`, + `"Destroying resource with UUID 1 and value 1"`, + `"Destroying resource with UUID 4 and value 3"`, + }, + getLogs(), + ) + }) +} diff --git a/runtime/tests/interpreter/memory_metering_test.go b/runtime/tests/interpreter/memory_metering_test.go index 3b25f8ae8a..095ca5fabd 100644 --- a/runtime/tests/interpreter/memory_metering_test.go +++ b/runtime/tests/interpreter/memory_metering_test.go @@ -71,12 +71,12 @@ func TestInterpretArrayMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: [Int8] = [] - let y: [[String]] = [[]] - let z: [[[Bool]]] = [[[]]] - } -` + fun main() { + let x: [Int8] = [] + let y: [[String]] = [[]] + let z: [[[Bool]]] = [[[]]] + } + ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -85,9 +85,9 @@ func TestInterpretArrayMetering(t *testing.T) { require.NoError(t, err) assert.Equal(t, uint64(25), meter.getMemory(common.MemoryKindArrayValueBase)) - assert.Equal(t, uint64(25), meter.getMemory(common.MemoryKindAtreeArrayDataSlab)) + assert.Equal(t, uint64(20), meter.getMemory(common.MemoryKindAtreeArrayDataSlab)) assert.Equal(t, uint64(0), meter.getMemory(common.MemoryKindAtreeArrayMetaDataSlab)) - assert.Equal(t, uint64(9), meter.getMemory(common.MemoryKindAtreeArrayElementOverhead)) + assert.Equal(t, uint64(8), meter.getMemory(common.MemoryKindAtreeArrayElementOverhead)) assert.Equal(t, uint64(4), meter.getMemory(common.MemoryKindVariable)) assert.Equal(t, uint64(1), meter.getMemory(common.MemoryKindElaboration)) // 1 Int8 for type @@ -104,10 +104,10 @@ func TestInterpretArrayMetering(t *testing.T) { t.Parallel() const script = ` - access(all) fun main() { + fun main() { let values: [[Int128]] = [[], [], []] for value in values { - let a = value + let a = value } } ` @@ -119,7 +119,7 @@ func TestInterpretArrayMetering(t *testing.T) { require.NoError(t, err) assert.Equal(t, uint64(30), meter.getMemory(common.MemoryKindArrayValueBase)) - assert.Equal(t, uint64(33), meter.getMemory(common.MemoryKindAtreeArrayDataSlab)) + assert.Equal(t, uint64(24), meter.getMemory(common.MemoryKindAtreeArrayDataSlab)) assert.Equal(t, uint64(3), meter.getMemory(common.MemoryKindAtreeArrayMetaDataSlab)) assert.Equal(t, uint64(9), meter.getMemory(common.MemoryKindAtreeArrayElementOverhead)) assert.Equal(t, uint64(8), meter.getMemory(common.MemoryKindVariable)) @@ -134,11 +134,11 @@ func TestInterpretArrayMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: [Int128] = [] - x.contains(5) - } -` + fun main() { + let x: [Int128] = [] + x.contains(5) + } + ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -157,12 +157,12 @@ func TestInterpretArrayMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: [Int8] = [] - x.append(3) - x.append(4) - } -` + fun main() { + let x: [Int8] = [] + x.append(3) + x.append(4) + } + ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -180,19 +180,19 @@ func TestInterpretArrayMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: [Int128] = [] // 2 data slabs - x.append(0) // fits in existing slab - x.append(1) // fits in existing slab - x.append(2) // adds 1 data and metadata slab - x.append(3) // fits in existing slab - x.append(4) // adds 1 data slab - x.append(5) // fits in existing slab - x.append(6) // adds 1 data slab - x.append(7) // fits in existing slab - x.append(8) // adds 1 data slab - } -` + fun main() { + let x: [Int128] = [] // 2 data slabs + x.append(0) // fits in existing slab + x.append(1) // fits in existing slab + x.append(2) // adds 1 data and metadata slab + x.append(3) // fits in existing slab + x.append(4) // adds 1 data slab + x.append(5) // fits in existing slab + x.append(6) // adds 1 data slab + x.append(7) // fits in existing slab + x.append(8) // adds 1 data slab + } + ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -210,15 +210,15 @@ func TestInterpretArrayMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - var i = 0; - let x: [Int128] = [] // 2 data slabs - while i < 120 { // should result in 4 meta data slabs and 60 slabs - x.append(0) - i = i + 1 - } - } -` + fun main() { + var i = 0; + let x: [Int128] = [] // 2 data slabs + while i < 120 { // should result in 4 meta data slabs and 60 slabs + x.append(0) + i = i + 1 + } + } + ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -236,12 +236,12 @@ func TestInterpretArrayMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: [Int128] = [] - x.insert(at:0, 3) - x.insert(at:1, 3) - } -` + fun main() { + let x: [Int128] = [] + x.insert(at: 0, 3) + x.insert(at: 1, 3) + } + ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -258,12 +258,12 @@ func TestInterpretArrayMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: [Int8] = [] - x.insert(at:0, 3) - x.insert(at:1, 3) - } -` + fun main() { + let x: [Int8] = [] + x.insert(at: 0, 3) + x.insert(at: 1, 3) + } + ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -282,12 +282,12 @@ func TestInterpretArrayMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: [Int128] = [0, 1, 2, 3] // uses 2 data slabs and 1 metadata slab - x[0] = 1 // adds 1 data and 1 metadata slab - x[2] = 1 // adds 1 data and 1 metadata slab - } -` + fun main() { + let x: [Int128] = [0, 1, 2, 3] // uses 2 data slabs and 1 metadata slab + x[0] = 1 // adds 1 data and 1 metadata slab + x[2] = 1 // adds 1 data and 1 metadata slab + } + ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -304,11 +304,11 @@ func TestInterpretArrayMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: [Int128] = [0, 1, 2] // uses 2 data slabs and 1 metadata slab - x[0] = 1 // fits in existing slab - x[2] = 1 // fits in existing slab - } + fun main() { + let x: [Int128] = [0, 1, 2] // uses 2 data slabs and 1 metadata slab + x[0] = 1 // fits in existing slab + x[2] = 1 // fits in existing slab + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -326,15 +326,15 @@ func TestInterpretArrayMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: [Int8; 0] = [] - let y: [Int8; 1] = [2] - let z: [Int8; 2] = [2, 4] - let w: [[Int8; 2]] = [[2, 4]] - let r: [[Int8; 2]] = [[2, 4], [8, 16]] - let q: [[Int8; 2]; 2] = [[2, 4], [8, 16]] - } -` + fun main() { + let x: [Int8; 0] = [] + let y: [Int8; 1] = [2] + let z: [Int8; 2] = [2, 4] + let w: [[Int8; 2]] = [[2, 4]] + let r: [[Int8; 2]] = [[2, 4], [8, 16]] + let q: [[Int8; 2]; 2] = [[2, 4], [8, 16]] + } + ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -342,9 +342,9 @@ func TestInterpretArrayMetering(t *testing.T) { require.NoError(t, err) assert.Equal(t, uint64(37), meter.getMemory(common.MemoryKindArrayValueBase)) - assert.Equal(t, uint64(37), meter.getMemory(common.MemoryKindAtreeArrayDataSlab)) + assert.Equal(t, uint64(32), meter.getMemory(common.MemoryKindAtreeArrayDataSlab)) assert.Equal(t, uint64(0), meter.getMemory(common.MemoryKindAtreeArrayMetaDataSlab)) - assert.Equal(t, uint64(66), meter.getMemory(common.MemoryKindAtreeArrayElementOverhead)) + assert.Equal(t, uint64(56), meter.getMemory(common.MemoryKindAtreeArrayElementOverhead)) // 1 for `w`: 1 for the element // 2 for `r`: 1 for each element @@ -359,16 +359,16 @@ func TestInterpretArrayMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: [Int128] = [] // 2 data slabs - x.insert(at:0, 3) // fits in existing slab - x.insert(at:1, 3) // fits in existing slab - x.insert(at:2, 3) // adds 1 metadata and data slab - x.insert(at:3, 3) // fits in existing slab - x.insert(at:4, 3) // adds 1 data slab - x.insert(at:5, 3) // fits in existing slab - } -` + fun main() { + let x: [Int128] = [] // 2 data slabs + x.insert(at:0, 3) // fits in existing slab + x.insert(at:1, 3) // fits in existing slab + x.insert(at:2, 3) // adds 1 metadata and data slab + x.insert(at:3, 3) // fits in existing slab + x.insert(at:4, 3) // adds 1 data slab + x.insert(at:5, 3) // fits in existing slab + } + ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -396,11 +396,11 @@ func TestInterpretDictionaryMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: {Int8: String} = {} - let y: {String: {Int8: String}} = {"a": {}} - } - ` + fun main() { + let x: {Int8: String} = {} + let y: {String: {Int8: String}} = {"a": {}} + } + ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -411,7 +411,7 @@ func TestInterpretDictionaryMetering(t *testing.T) { assert.Equal(t, uint64(2), meter.getMemory(common.MemoryKindStringValue)) assert.Equal(t, uint64(9), meter.getMemory(common.MemoryKindDictionaryValueBase)) assert.Equal(t, uint64(2), meter.getMemory(common.MemoryKindAtreeMapElementOverhead)) - assert.Equal(t, uint64(9), meter.getMemory(common.MemoryKindAtreeMapDataSlab)) + assert.Equal(t, uint64(8), meter.getMemory(common.MemoryKindAtreeMapDataSlab)) assert.Equal(t, uint64(0), meter.getMemory(common.MemoryKindAtreeMapMetaDataSlab)) assert.Equal(t, uint64(159), meter.getMemory(common.MemoryKindAtreeMapPreAllocatedElement)) assert.Equal(t, uint64(3), meter.getMemory(common.MemoryKindVariable)) @@ -428,13 +428,13 @@ func TestInterpretDictionaryMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let values: [{Int8: String}] = [{}, {}, {}] - for value in values { - let a = value - } - } - ` + fun main() { + let values: [{Int8: String}] = [{}, {}, {}] + for value in values { + let a = value + } + } + ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -459,11 +459,11 @@ func TestInterpretDictionaryMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: {Int8: String} = {} - x.containsKey(5) - } - ` + fun main() { + let x: {Int8: String} = {} + x.containsKey(5) + } + ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -478,12 +478,12 @@ func TestInterpretDictionaryMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: {Int8: String} = {} - x.insert(key: 5, "") - x.insert(key: 4, "") - } - ` + fun main() { + let x: {Int8: String} = {} + x.insert(key: 5, "") + x.insert(key: 4, "") + } + ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -504,19 +504,19 @@ func TestInterpretDictionaryMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: {Int8: String} = {} // 2 data slabs - x.insert(key: 0, "") // fits in slab - x.insert(key: 1, "") // fits in slab - x.insert(key: 2, "") // adds 1 data and metadata slab - x.insert(key: 3, "") // fits in slab - x.insert(key: 4, "") // adds 1 data slab - x.insert(key: 5, "") // fits in slab - x.insert(key: 6, "") // adds 1 data slab - x.insert(key: 7, "") // fits in slab - x.insert(key: 8, "") // adds 1 data slab - } - ` + fun main() { + let x: {Int8: String} = {} // 2 data slabs + x.insert(key: 0, "") // fits in slab + x.insert(key: 1, "") // fits in slab + x.insert(key: 2, "") // adds 1 data and metadata slab + x.insert(key: 3, "") // fits in slab + x.insert(key: 4, "") // adds 1 data slab + x.insert(key: 5, "") // fits in slab + x.insert(key: 6, "") // adds 1 data slab + x.insert(key: 7, "") // fits in slab + x.insert(key: 8, "") // adds 1 data slab + } + ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -535,19 +535,19 @@ func TestInterpretDictionaryMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: {Int8: Int8} = {} // 2 data slabs - x.insert(key: 0, 0) // all fit in slab - x.insert(key: 1, 1) - x.insert(key: 2, 2) - x.insert(key: 3, 3) - x.insert(key: 4, 4) - x.insert(key: 5, 5) - x.insert(key: 6, 6) - x.insert(key: 7, 7) - x.insert(key: 8, 8) - } - ` + fun main() { + let x: {Int8: Int8} = {} // 2 data slabs + x.insert(key: 0, 0) // all fit in slab + x.insert(key: 1, 1) + x.insert(key: 2, 2) + x.insert(key: 3, 3) + x.insert(key: 4, 4) + x.insert(key: 5, 5) + x.insert(key: 6, 6) + x.insert(key: 7, 7) + x.insert(key: 8, 8) + } + ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -566,12 +566,12 @@ func TestInterpretDictionaryMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: {Int8: String} = {3: "a"} // 2 data slabs - x[3] = "b" // fits in existing slab - x[3] = "c" // fits in existing slab - x[4] = "d" // fits in existing slab - } + fun main() { + let x: {Int8: String} = {3: "a"} // 2 data slabs + x[3] = "b" // fits in existing slab + x[3] = "c" // fits in existing slab + x[4] = "d" // fits in existing slab + } ` meter := newTestMemoryGauge() @@ -591,12 +591,12 @@ func TestInterpretDictionaryMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: {Int8: String} = {3: "a"} // 2 data slabs - x[3] = "b" // fits in existing slab - x[4] = "d" // fits in existing slab - x[3] = "c" // adds 1 data slab and metadata slab - } + fun main() { + let x: {Int8: String} = {3: "a"} // 2 data slabs + x[3] = "b" // fits in existing slab + x[4] = "d" // fits in existing slab + x[3] = "c" // adds 1 data slab and metadata slab + } ` meter := newTestMemoryGauge() @@ -618,23 +618,23 @@ func TestInterpretCompositeMetering(t *testing.T) { t.Parallel() script := ` - access(all) struct S {} + struct S {} - access(all) resource R { - access(all) let a: String - access(all) let b: String + resource R { + let a: String + let b: String - init(a: String, b: String) { - self.a = a - self.b = b - } - } + init(a: String, b: String) { + self.a = a + self.b = b + } + } - access(all) fun main() { - let s = S() - let r <- create R(a: "a", b: "b") - destroy r - } + fun main() { + let s = S() + let r <- create R(a: "a", b: "b") + destroy r + } ` meter := newTestMemoryGauge() @@ -646,9 +646,9 @@ func TestInterpretCompositeMetering(t *testing.T) { assert.Equal(t, uint64(6), meter.getMemory(common.MemoryKindStringValue)) assert.Equal(t, uint64(72), meter.getMemory(common.MemoryKindRawString)) assert.Equal(t, uint64(4), meter.getMemory(common.MemoryKindCompositeValueBase)) - assert.Equal(t, uint64(5), meter.getMemory(common.MemoryKindAtreeMapDataSlab)) - assert.Equal(t, uint64(1), meter.getMemory(common.MemoryKindAtreeMapMetaDataSlab)) - assert.Equal(t, uint64(4), meter.getMemory(common.MemoryKindAtreeMapElementOverhead)) + assert.Equal(t, uint64(3), meter.getMemory(common.MemoryKindAtreeMapDataSlab)) + assert.Equal(t, uint64(0), meter.getMemory(common.MemoryKindAtreeMapMetaDataSlab)) + assert.Equal(t, uint64(1), meter.getMemory(common.MemoryKindAtreeMapElementOverhead)) assert.Equal(t, uint64(32), meter.getMemory(common.MemoryKindAtreeMapPreAllocatedElement)) assert.Equal(t, uint64(8), meter.getMemory(common.MemoryKindVariable)) assert.Equal(t, uint64(2), meter.getMemory(common.MemoryKindCompositeStaticType)) @@ -661,14 +661,14 @@ func TestInterpretCompositeMetering(t *testing.T) { t.Parallel() script := ` - access(all) struct S {} + struct S {} - access(all) fun main() { - let values = [S(), S(), S()] - for value in values { + fun main() { + let values = [S(), S(), S()] + for value in values { let a = value - } - } + } + } ` meter := newTestMemoryGauge() @@ -678,7 +678,7 @@ func TestInterpretCompositeMetering(t *testing.T) { require.NoError(t, err) assert.Equal(t, uint64(27), meter.getMemory(common.MemoryKindCompositeValueBase)) - assert.Equal(t, uint64(27), meter.getMemory(common.MemoryKindAtreeMapDataSlab)) + assert.Equal(t, uint64(18), meter.getMemory(common.MemoryKindAtreeMapDataSlab)) assert.Equal(t, uint64(0), meter.getMemory(common.MemoryKindAtreeMapElementOverhead)) assert.Equal(t, uint64(480), meter.getMemory(common.MemoryKindAtreeMapPreAllocatedElement)) assert.Equal(t, uint64(9), meter.getMemory(common.MemoryKindVariable)) @@ -697,7 +697,7 @@ func TestInterpretSimpleCompositeMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main(a: &Account) {} + fun main(a: &Account) {} ` meter := newTestMemoryGauge() @@ -727,8 +727,9 @@ func TestInterpretCompositeFieldMetering(t *testing.T) { t.Parallel() script := ` - access(all) struct S {} - access(all) fun main() { + struct S {} + + fun main() { let s = S() } ` @@ -750,15 +751,17 @@ func TestInterpretCompositeFieldMetering(t *testing.T) { t.Parallel() script := ` - access(all) struct S { - access(all) let a: String - init(_ a: String) { - self.a = a - } - } - access(all) fun main() { - let s = S("a") - } + struct S { + let a: String + + init(_ a: String) { + self.a = a + } + } + + fun main() { + let s = S("a") + } ` meter := newTestMemoryGauge() @@ -779,17 +782,19 @@ func TestInterpretCompositeFieldMetering(t *testing.T) { t.Parallel() script := ` - access(all) struct S { - access(all) let a: String - access(all) let b: String - init(_ a: String, _ b: String) { - self.a = a - self.b = b - } - } - access(all) fun main() { - let s = S("a", "b") - } + struct S { + let a: String + let b: String + + init(_ a: String, _ b: String) { + self.a = a + self.b = b + } + } + + fun main() { + let s = S("a", "b") + } ` meter := newTestMemoryGauge() @@ -814,7 +819,7 @@ func TestInterpretInterpretedFunctionMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() {} + fun main() {} ` meter := newTestMemoryGauge() @@ -831,11 +836,11 @@ func TestInterpretInterpretedFunctionMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let funcPointer = fun(a: String): String { - return a - } - } + fun main() { + let funcPointer = fun(a: String): String { + return a + } + } ` meter := newTestMemoryGauge() @@ -852,16 +857,16 @@ func TestInterpretInterpretedFunctionMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let funcPointer1 = fun(a: String): String { - return a - } + fun main() { + let funcPointer1 = fun(a: String): String { + return a + } - let funcPointer2 = funcPointer1 - let funcPointer3 = funcPointer2 + let funcPointer2 = funcPointer1 + let funcPointer3 = funcPointer2 - let value = funcPointer3("hello") - } + let value = funcPointer3("hello") + } ` meter := newTestMemoryGauge() @@ -881,11 +886,11 @@ func TestInterpretInterpretedFunctionMetering(t *testing.T) { t.Parallel() script := ` - access(all) struct Foo { - access(all) fun bar() {} - } + struct Foo { + fun bar() {} + } - access(all) fun main() {} + fun main() {} ` meter := newTestMemoryGauge() @@ -902,11 +907,11 @@ func TestInterpretInterpretedFunctionMetering(t *testing.T) { t.Parallel() script := ` - access(all) struct Foo { - init() {} - } + struct Foo { + init() {} + } - access(all) fun main() {} + fun main() {} ` meter := newTestMemoryGauge() @@ -929,7 +934,7 @@ func TestInterpretHostFunctionMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() {} + fun main() {} ` meter := newTestMemoryGauge() @@ -944,16 +949,16 @@ func TestInterpretHostFunctionMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let funcPointer1 = fun(a: String): String { - return a - } + fun main() { + let funcPointer1 = fun(a: String): String { + return a + } - let funcPointer2 = funcPointer1 - let funcPointer3 = funcPointer2 + let funcPointer2 = funcPointer1 + let funcPointer3 = funcPointer2 - let value = funcPointer3("hello") - } + let value = funcPointer3("hello") + } ` meter := newTestMemoryGauge() @@ -968,11 +973,11 @@ func TestInterpretHostFunctionMetering(t *testing.T) { t.Parallel() script := ` - access(all) struct Foo { - access(all) fun bar() {} - } + struct Foo { + fun bar() {} + } - access(all) fun main() {} + fun main() {} ` meter := newTestMemoryGauge() @@ -989,11 +994,11 @@ func TestInterpretHostFunctionMetering(t *testing.T) { t.Parallel() script := ` - access(all) struct Foo { - init() {} - } + struct Foo { + init() {} + } - access(all) fun main() {} + fun main() {} ` meter := newTestMemoryGauge() @@ -1010,11 +1015,11 @@ func TestInterpretHostFunctionMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let a = Int8(5) + fun main() { + let a = Int8(5) - let b = CompositeType("PublicKey") - } + let b = CompositeType("PublicKey") + } ` meter := newTestMemoryGauge() @@ -1033,9 +1038,9 @@ func TestInterpretHostFunctionMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - assert(true) - } + fun main() { + assert(true) + } ` meter := newTestMemoryGauge() @@ -1073,12 +1078,12 @@ func TestInterpretHostFunctionMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let publicKey = PublicKey( - publicKey: "0102".decodeHex(), - signatureAlgorithm: SignatureAlgorithm.ECDSA_P256 - ) - } + fun main() { + let publicKey = PublicKey( + publicKey: "0102".decodeHex(), + signatureAlgorithm: SignatureAlgorithm.ECDSA_P256 + ) + } ` baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) @@ -1122,17 +1127,17 @@ func TestInterpretHostFunctionMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let publicKey1 = PublicKey( - publicKey: "0102".decodeHex(), - signatureAlgorithm: SignatureAlgorithm.ECDSA_P256 - ) + fun main() { + let publicKey1 = PublicKey( + publicKey: "0102".decodeHex(), + signatureAlgorithm: SignatureAlgorithm.ECDSA_P256 + ) - let publicKey2 = PublicKey( - publicKey: "0102".decodeHex(), - signatureAlgorithm: SignatureAlgorithm.ECDSA_P256 - ) - } + let publicKey2 = PublicKey( + publicKey: "0102".decodeHex(), + signatureAlgorithm: SignatureAlgorithm.ECDSA_P256 + ) + } ` baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) @@ -1180,11 +1185,11 @@ func TestInterpretBoundFunctionMetering(t *testing.T) { t.Parallel() script := ` - access(all) struct Foo { - access(all) fun bar() {} - } + struct Foo { + fun bar() {} + } - access(all) fun main() {} + fun main() {} ` meter := newTestMemoryGauge() @@ -1201,11 +1206,11 @@ func TestInterpretBoundFunctionMetering(t *testing.T) { t.Parallel() script := ` - access(all) struct Foo { - init() {} - } + struct Foo { + init() {} + } - access(all) fun main() {} + fun main() {} ` meter := newTestMemoryGauge() @@ -1222,16 +1227,16 @@ func TestInterpretBoundFunctionMetering(t *testing.T) { t.Parallel() script := ` - access(all) struct Foo { - access(all) fun bar() {} - } + struct Foo { + fun bar() {} + } - access(all) fun main() { - let foo = Foo() - foo.bar() - foo.bar() - foo.bar() - } + fun main() { + let foo = Foo() + foo.bar() + foo.bar() + foo.bar() + } ` meter := newTestMemoryGauge() @@ -1253,9 +1258,9 @@ func TestInterpretOptionalValueMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: String? = "hello" - } + fun main() { + let x: String? = "hello" + } ` meter := newTestMemoryGauge() @@ -1271,11 +1276,11 @@ func TestInterpretOptionalValueMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: {Int8: String} = {1: "foo", 2: "bar"} - let y = x[0] - let z = x[1] - } + fun main() { + let x: {Int8: String} = {1: "foo", 2: "bar"} + let y = x[0] + let z = x[1] + } ` meter := newTestMemoryGauge() @@ -1295,11 +1300,11 @@ func TestInterpretOptionalValueMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: {Int8: String} = {1: "foo", 2: "bar"} - x[0] = "a" - x[1] = "b" - } + fun main() { + let x: {Int8: String} = {1: "foo", 2: "bar"} + x[0] = "a" + x[1] = "b" + } ` meter := newTestMemoryGauge() @@ -1318,10 +1323,10 @@ func TestInterpretOptionalValueMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let type: Type = Type() - let a = OptionalType(type) - } + fun main() { + let type: Type = Type() + let a = OptionalType(type) + } ` meter := newTestMemoryGauge() @@ -1346,9 +1351,9 @@ func TestInterpretIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 - } + fun main() { + let x = 1 + } ` meter := newTestMemoryGauge() @@ -1365,9 +1370,9 @@ func TestInterpretIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 + 2 - } + fun main() { + let x = 1 + 2 + } ` meter := newTestMemoryGauge() @@ -1384,9 +1389,9 @@ func TestInterpretIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 - 2 - } + fun main() { + let x = 1 - 2 + } ` meter := newTestMemoryGauge() @@ -1403,9 +1408,9 @@ func TestInterpretIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 * 2 - } + fun main() { + let x = 1 * 2 + } ` meter := newTestMemoryGauge() @@ -1422,9 +1427,9 @@ func TestInterpretIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 / 2 - } + fun main() { + let x = 10 / 2 + } ` meter := newTestMemoryGauge() @@ -1441,9 +1446,9 @@ func TestInterpretIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 % 2 - } + fun main() { + let x = 10 % 2 + } ` meter := newTestMemoryGauge() @@ -1460,9 +1465,9 @@ func TestInterpretIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 | 2 - } + fun main() { + let x = 10 | 2 + } ` meter := newTestMemoryGauge() @@ -1479,9 +1484,9 @@ func TestInterpretIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 ^ 2 - } + fun main() { + let x = 10 ^ 2 + } ` meter := newTestMemoryGauge() @@ -1498,9 +1503,9 @@ func TestInterpretIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 & 2 - } + fun main() { + let x = 10 & 2 + } ` meter := newTestMemoryGauge() @@ -1517,9 +1522,9 @@ func TestInterpretIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 << 2 - } + fun main() { + let x = 10 << 2 + } ` meter := newTestMemoryGauge() @@ -1536,9 +1541,9 @@ func TestInterpretIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 >> 2 - } + fun main() { + let x = 10 >> 2 + } ` meter := newTestMemoryGauge() @@ -1555,10 +1560,10 @@ func TestInterpretIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 - let y = -x - } + fun main() { + let x = 1 + let y = -x + } ` meter := newTestMemoryGauge() @@ -1580,9 +1585,9 @@ func TestInterpretUIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as UInt - } + fun main() { + let x = 1 as UInt + } ` meter := newTestMemoryGauge() @@ -1600,9 +1605,9 @@ func TestInterpretUIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as UInt + 2 as UInt - } + fun main() { + let x = 1 as UInt + 2 as UInt + } ` meter := newTestMemoryGauge() @@ -1619,9 +1624,9 @@ func TestInterpretUIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 3 as UInt - 2 as UInt - } + fun main() { + let x = 3 as UInt - 2 as UInt + } ` meter := newTestMemoryGauge() @@ -1638,9 +1643,9 @@ func TestInterpretUIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = (1 as UInt).saturatingSubtract(2 as UInt) - } + fun main() { + let x = (1 as UInt).saturatingSubtract(2 as UInt) + } ` meter := newTestMemoryGauge() @@ -1657,9 +1662,9 @@ func TestInterpretUIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as UInt * 2 as UInt - } + fun main() { + let x = 1 as UInt * 2 as UInt + } ` meter := newTestMemoryGauge() @@ -1676,9 +1681,9 @@ func TestInterpretUIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt / 2 as UInt - } + fun main() { + let x = 10 as UInt / 2 as UInt + } ` meter := newTestMemoryGauge() @@ -1695,9 +1700,9 @@ func TestInterpretUIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt % 2 as UInt - } + fun main() { + let x = 10 as UInt % 2 as UInt + } ` meter := newTestMemoryGauge() @@ -1714,9 +1719,9 @@ func TestInterpretUIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt | 2 as UInt - } + fun main() { + let x = 10 as UInt | 2 as UInt + } ` meter := newTestMemoryGauge() @@ -1733,9 +1738,9 @@ func TestInterpretUIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt ^ 2 as UInt - } + fun main() { + let x = 10 as UInt ^ 2 as UInt + } ` meter := newTestMemoryGauge() @@ -1752,9 +1757,9 @@ func TestInterpretUIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt & 2 as UInt - } + fun main() { + let x = 10 as UInt & 2 as UInt + } ` meter := newTestMemoryGauge() @@ -1771,9 +1776,9 @@ func TestInterpretUIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt << 2 as UInt - } + fun main() { + let x = 10 as UInt << 2 as UInt + } ` meter := newTestMemoryGauge() @@ -1790,9 +1795,9 @@ func TestInterpretUIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt >> 2 as UInt - } + fun main() { + let x = 10 as UInt >> 2 as UInt + } ` meter := newTestMemoryGauge() @@ -1809,10 +1814,10 @@ func TestInterpretUIntMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 - let y = -x - } + fun main() { + let x = 1 + let y = -x + } ` meter := newTestMemoryGauge() @@ -1834,9 +1839,9 @@ func TestInterpretUInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as UInt8 - } + fun main() { + let x = 1 as UInt8 + } ` meter := newTestMemoryGauge() @@ -1854,9 +1859,9 @@ func TestInterpretUInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as UInt8 + 2 as UInt8 - } + fun main() { + let x = 1 as UInt8 + 2 as UInt8 + } ` meter := newTestMemoryGauge() @@ -1875,9 +1880,9 @@ func TestInterpretUInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = (1 as UInt8).saturatingAdd(2 as UInt8) - } + fun main() { + let x = (1 as UInt8).saturatingAdd(2 as UInt8) + } ` meter := newTestMemoryGauge() @@ -1896,9 +1901,9 @@ func TestInterpretUInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 3 as UInt8 - 2 as UInt8 - } + fun main() { + let x = 3 as UInt8 - 2 as UInt8 + } ` meter := newTestMemoryGauge() @@ -1917,9 +1922,9 @@ func TestInterpretUInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = (1 as UInt8).saturatingSubtract(2 as UInt8) - } + fun main() { + let x = (1 as UInt8).saturatingSubtract(2 as UInt8) + } ` meter := newTestMemoryGauge() @@ -1938,9 +1943,9 @@ func TestInterpretUInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as UInt8 * 2 as UInt8 - } + fun main() { + let x = 1 as UInt8 * 2 as UInt8 + } ` meter := newTestMemoryGauge() @@ -1959,9 +1964,9 @@ func TestInterpretUInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = (1 as UInt8).saturatingMultiply(2 as UInt8) - } + fun main() { + let x = (1 as UInt8).saturatingMultiply(2 as UInt8) + } ` meter := newTestMemoryGauge() @@ -1980,9 +1985,9 @@ func TestInterpretUInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt8 / 2 as UInt8 - } + fun main() { + let x = 10 as UInt8 / 2 as UInt8 + } ` meter := newTestMemoryGauge() @@ -2001,9 +2006,9 @@ func TestInterpretUInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt8 % 2 as UInt8 - } + fun main() { + let x = 10 as UInt8 % 2 as UInt8 + } ` meter := newTestMemoryGauge() @@ -2022,9 +2027,9 @@ func TestInterpretUInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt8 | 2 as UInt8 - } + fun main() { + let x = 10 as UInt8 | 2 as UInt8 + } ` meter := newTestMemoryGauge() @@ -2043,9 +2048,9 @@ func TestInterpretUInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt8 ^ 2 as UInt8 - } + fun main() { + let x = 10 as UInt8 ^ 2 as UInt8 + } ` meter := newTestMemoryGauge() @@ -2064,9 +2069,9 @@ func TestInterpretUInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt8 & 2 as UInt8 - } + fun main() { + let x = 10 as UInt8 & 2 as UInt8 + } ` meter := newTestMemoryGauge() @@ -2086,9 +2091,9 @@ func TestInterpretUInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt8 << 2 as UInt8 - } + fun main() { + let x = 10 as UInt8 << 2 as UInt8 + } ` meter := newTestMemoryGauge() @@ -2107,9 +2112,9 @@ func TestInterpretUInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt8 >> 2 as UInt8 - } + fun main() { + let x = 10 as UInt8 >> 2 as UInt8 + } ` meter := newTestMemoryGauge() @@ -2133,9 +2138,9 @@ func TestInterpretUInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as UInt16 - } + fun main() { + let x = 1 as UInt16 + } ` meter := newTestMemoryGauge() @@ -2153,9 +2158,9 @@ func TestInterpretUInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as UInt16 + 2 as UInt16 - } + fun main() { + let x = 1 as UInt16 + 2 as UInt16 + } ` meter := newTestMemoryGauge() @@ -2174,9 +2179,9 @@ func TestInterpretUInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = (1 as UInt16).saturatingAdd(2 as UInt16) - } + fun main() { + let x = (1 as UInt16).saturatingAdd(2 as UInt16) + } ` meter := newTestMemoryGauge() @@ -2195,9 +2200,9 @@ func TestInterpretUInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 3 as UInt16 - 2 as UInt16 - } + fun main() { + let x = 3 as UInt16 - 2 as UInt16 + } ` meter := newTestMemoryGauge() @@ -2216,9 +2221,9 @@ func TestInterpretUInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = (1 as UInt16).saturatingSubtract(2 as UInt16) - } + fun main() { + let x = (1 as UInt16).saturatingSubtract(2 as UInt16) + } ` meter := newTestMemoryGauge() @@ -2237,9 +2242,9 @@ func TestInterpretUInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as UInt16 * 2 as UInt16 - } + fun main() { + let x = 1 as UInt16 * 2 as UInt16 + } ` meter := newTestMemoryGauge() @@ -2258,9 +2263,9 @@ func TestInterpretUInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = (1 as UInt16).saturatingMultiply(2 as UInt16) - } + fun main() { + let x = (1 as UInt16).saturatingMultiply(2 as UInt16) + } ` meter := newTestMemoryGauge() @@ -2279,9 +2284,9 @@ func TestInterpretUInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt16 / 2 as UInt16 - } + fun main() { + let x = 10 as UInt16 / 2 as UInt16 + } ` meter := newTestMemoryGauge() @@ -2300,9 +2305,9 @@ func TestInterpretUInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt16 % 2 as UInt16 - } + fun main() { + let x = 10 as UInt16 % 2 as UInt16 + } ` meter := newTestMemoryGauge() @@ -2321,9 +2326,9 @@ func TestInterpretUInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt16 | 2 as UInt16 - } + fun main() { + let x = 10 as UInt16 | 2 as UInt16 + } ` meter := newTestMemoryGauge() @@ -2342,9 +2347,9 @@ func TestInterpretUInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt16 ^ 2 as UInt16 - } + fun main() { + let x = 10 as UInt16 ^ 2 as UInt16 + } ` meter := newTestMemoryGauge() @@ -2363,9 +2368,9 @@ func TestInterpretUInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt16 & 2 as UInt16 - } + fun main() { + let x = 10 as UInt16 & 2 as UInt16 + } ` meter := newTestMemoryGauge() @@ -2384,9 +2389,9 @@ func TestInterpretUInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt16 << 2 as UInt16 - } + fun main() { + let x = 10 as UInt16 << 2 as UInt16 + } ` meter := newTestMemoryGauge() @@ -2405,9 +2410,9 @@ func TestInterpretUInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt16 >> 2 as UInt16 - } + fun main() { + let x = 10 as UInt16 >> 2 as UInt16 + } ` meter := newTestMemoryGauge() @@ -2431,9 +2436,9 @@ func TestInterpretUInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as UInt32 - } + fun main() { + let x = 1 as UInt32 + } ` meter := newTestMemoryGauge() @@ -2451,9 +2456,9 @@ func TestInterpretUInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as UInt32 + 2 as UInt32 - } + fun main() { + let x = 1 as UInt32 + 2 as UInt32 + } ` meter := newTestMemoryGauge() @@ -2472,9 +2477,9 @@ func TestInterpretUInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = (1 as UInt32).saturatingAdd(2 as UInt32) - } + fun main() { + let x = (1 as UInt32).saturatingAdd(2 as UInt32) + } ` meter := newTestMemoryGauge() @@ -2493,9 +2498,9 @@ func TestInterpretUInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 3 as UInt32 - 2 as UInt32 - } + fun main() { + let x = 3 as UInt32 - 2 as UInt32 + } ` meter := newTestMemoryGauge() @@ -2514,9 +2519,9 @@ func TestInterpretUInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = (1 as UInt32).saturatingSubtract(2 as UInt32) - } + fun main() { + let x = (1 as UInt32).saturatingSubtract(2 as UInt32) + } ` meter := newTestMemoryGauge() @@ -2535,9 +2540,9 @@ func TestInterpretUInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as UInt32 * 2 as UInt32 - } + fun main() { + let x = 1 as UInt32 * 2 as UInt32 + } ` meter := newTestMemoryGauge() @@ -2556,9 +2561,9 @@ func TestInterpretUInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = (1 as UInt32).saturatingMultiply(2 as UInt32) - } + fun main() { + let x = (1 as UInt32).saturatingMultiply(2 as UInt32) + } ` meter := newTestMemoryGauge() @@ -2577,9 +2582,9 @@ func TestInterpretUInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt32 / 2 as UInt32 - } + fun main() { + let x = 10 as UInt32 / 2 as UInt32 + } ` meter := newTestMemoryGauge() @@ -2598,9 +2603,9 @@ func TestInterpretUInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt32 % 2 as UInt32 - } + fun main() { + let x = 10 as UInt32 % 2 as UInt32 + } ` meter := newTestMemoryGauge() @@ -2619,9 +2624,9 @@ func TestInterpretUInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt32 | 2 as UInt32 - } + fun main() { + let x = 10 as UInt32 | 2 as UInt32 + } ` meter := newTestMemoryGauge() @@ -2640,9 +2645,9 @@ func TestInterpretUInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt32 ^ 2 as UInt32 - } + fun main() { + let x = 10 as UInt32 ^ 2 as UInt32 + } ` meter := newTestMemoryGauge() @@ -2661,9 +2666,9 @@ func TestInterpretUInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt32 & 2 as UInt32 - } + fun main() { + let x = 10 as UInt32 & 2 as UInt32 + } ` meter := newTestMemoryGauge() @@ -2682,9 +2687,9 @@ func TestInterpretUInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt32 << 2 as UInt32 - } + fun main() { + let x = 10 as UInt32 << 2 as UInt32 + } ` meter := newTestMemoryGauge() @@ -2703,9 +2708,9 @@ func TestInterpretUInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt32 >> 2 as UInt32 - } + fun main() { + let x = 10 as UInt32 >> 2 as UInt32 + } ` meter := newTestMemoryGauge() @@ -2729,9 +2734,9 @@ func TestInterpretUInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as UInt64 - } + fun main() { + let x = 1 as UInt64 + } ` meter := newTestMemoryGauge() @@ -2749,9 +2754,9 @@ func TestInterpretUInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as UInt64 + 2 as UInt64 - } + fun main() { + let x = 1 as UInt64 + 2 as UInt64 + } ` meter := newTestMemoryGauge() @@ -2770,9 +2775,9 @@ func TestInterpretUInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = (1 as UInt64).saturatingAdd(2 as UInt64) - } + fun main() { + let x = (1 as UInt64).saturatingAdd(2 as UInt64) + } ` meter := newTestMemoryGauge() @@ -2791,9 +2796,9 @@ func TestInterpretUInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 3 as UInt64 - 2 as UInt64 - } + fun main() { + let x = 3 as UInt64 - 2 as UInt64 + } ` meter := newTestMemoryGauge() @@ -2812,9 +2817,9 @@ func TestInterpretUInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = (1 as UInt64).saturatingSubtract(2 as UInt64) - } + fun main() { + let x = (1 as UInt64).saturatingSubtract(2 as UInt64) + } ` meter := newTestMemoryGauge() @@ -2833,9 +2838,9 @@ func TestInterpretUInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as UInt64 * 2 as UInt64 - } + fun main() { + let x = 1 as UInt64 * 2 as UInt64 + } ` meter := newTestMemoryGauge() @@ -2854,9 +2859,9 @@ func TestInterpretUInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = (1 as UInt64).saturatingMultiply(2 as UInt64) - } + fun main() { + let x = (1 as UInt64).saturatingMultiply(2 as UInt64) + } ` meter := newTestMemoryGauge() @@ -2875,9 +2880,9 @@ func TestInterpretUInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt64 / 2 as UInt64 - } + fun main() { + let x = 10 as UInt64 / 2 as UInt64 + } ` meter := newTestMemoryGauge() @@ -2896,9 +2901,9 @@ func TestInterpretUInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt64 % 2 as UInt64 - } + fun main() { + let x = 10 as UInt64 % 2 as UInt64 + } ` meter := newTestMemoryGauge() @@ -2917,9 +2922,9 @@ func TestInterpretUInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt64 | 2 as UInt64 - } + fun main() { + let x = 10 as UInt64 | 2 as UInt64 + } ` meter := newTestMemoryGauge() @@ -2938,9 +2943,9 @@ func TestInterpretUInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt64 ^ 2 as UInt64 - } + fun main() { + let x = 10 as UInt64 ^ 2 as UInt64 + } ` meter := newTestMemoryGauge() @@ -2959,9 +2964,9 @@ func TestInterpretUInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt64 & 2 as UInt64 - } + fun main() { + let x = 10 as UInt64 & 2 as UInt64 + } ` meter := newTestMemoryGauge() @@ -2980,9 +2985,9 @@ func TestInterpretUInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt64 << 2 as UInt64 - } + fun main() { + let x = 10 as UInt64 << 2 as UInt64 + } ` meter := newTestMemoryGauge() @@ -3001,9 +3006,9 @@ func TestInterpretUInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt64 >> 2 as UInt64 - } + fun main() { + let x = 10 as UInt64 >> 2 as UInt64 + } ` meter := newTestMemoryGauge() @@ -3027,9 +3032,9 @@ func TestInterpretUInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as UInt128 - } + fun main() { + let x = 1 as UInt128 + } ` meter := newTestMemoryGauge() @@ -3047,9 +3052,9 @@ func TestInterpretUInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as UInt128 + 2 as UInt128 - } + fun main() { + let x = 1 as UInt128 + 2 as UInt128 + } ` meter := newTestMemoryGauge() @@ -3068,9 +3073,9 @@ func TestInterpretUInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = (1 as UInt128).saturatingAdd(2 as UInt128) - } + fun main() { + let x = (1 as UInt128).saturatingAdd(2 as UInt128) + } ` meter := newTestMemoryGauge() @@ -3089,9 +3094,9 @@ func TestInterpretUInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 3 as UInt128 - 2 as UInt128 - } + fun main() { + let x = 3 as UInt128 - 2 as UInt128 + } ` meter := newTestMemoryGauge() @@ -3110,9 +3115,9 @@ func TestInterpretUInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = (1 as UInt128).saturatingSubtract(2 as UInt128) - } + fun main() { + let x = (1 as UInt128).saturatingSubtract(2 as UInt128) + } ` meter := newTestMemoryGauge() @@ -3132,9 +3137,9 @@ func TestInterpretUInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as UInt128 * 2 as UInt128 - } + fun main() { + let x = 1 as UInt128 * 2 as UInt128 + } ` meter := newTestMemoryGauge() @@ -3153,9 +3158,9 @@ func TestInterpretUInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = (1 as UInt128).saturatingMultiply(2 as UInt128) - } + fun main() { + let x = (1 as UInt128).saturatingMultiply(2 as UInt128) + } ` meter := newTestMemoryGauge() @@ -3174,9 +3179,9 @@ func TestInterpretUInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt128 / 2 as UInt128 - } + fun main() { + let x = 10 as UInt128 / 2 as UInt128 + } ` meter := newTestMemoryGauge() @@ -3195,9 +3200,9 @@ func TestInterpretUInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt128 % 2 as UInt128 - } + fun main() { + let x = 10 as UInt128 % 2 as UInt128 + } ` meter := newTestMemoryGauge() @@ -3216,9 +3221,9 @@ func TestInterpretUInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt128 | 2 as UInt128 - } + fun main() { + let x = 10 as UInt128 | 2 as UInt128 + } ` meter := newTestMemoryGauge() @@ -3237,9 +3242,9 @@ func TestInterpretUInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt128 ^ 2 as UInt128 - } + fun main() { + let x = 10 as UInt128 ^ 2 as UInt128 + } ` meter := newTestMemoryGauge() @@ -3258,9 +3263,9 @@ func TestInterpretUInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt128 & 2 as UInt128 - } + fun main() { + let x = 10 as UInt128 & 2 as UInt128 + } ` meter := newTestMemoryGauge() @@ -3279,9 +3284,9 @@ func TestInterpretUInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt128 << 2 as UInt128 - } + fun main() { + let x = 10 as UInt128 << 2 as UInt128 + } ` meter := newTestMemoryGauge() @@ -3300,9 +3305,9 @@ func TestInterpretUInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt128 >> 2 as UInt128 - } + fun main() { + let x = 10 as UInt128 >> 2 as UInt128 + } ` meter := newTestMemoryGauge() @@ -3326,9 +3331,9 @@ func TestInterpretUInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as UInt256 - } + fun main() { + let x = 1 as UInt256 + } ` meter := newTestMemoryGauge() @@ -3346,9 +3351,9 @@ func TestInterpretUInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as UInt256 + 2 as UInt256 - } + fun main() { + let x = 1 as UInt256 + 2 as UInt256 + } ` meter := newTestMemoryGauge() @@ -3367,9 +3372,9 @@ func TestInterpretUInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = (1 as UInt256).saturatingAdd(2 as UInt256) - } + fun main() { + let x = (1 as UInt256).saturatingAdd(2 as UInt256) + } ` meter := newTestMemoryGauge() @@ -3388,9 +3393,9 @@ func TestInterpretUInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 3 as UInt256 - 2 as UInt256 - } + fun main() { + let x = 3 as UInt256 - 2 as UInt256 + } ` meter := newTestMemoryGauge() @@ -3409,9 +3414,9 @@ func TestInterpretUInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = (1 as UInt256).saturatingSubtract(2 as UInt256) - } + fun main() { + let x = (1 as UInt256).saturatingSubtract(2 as UInt256) + } ` meter := newTestMemoryGauge() @@ -3430,9 +3435,9 @@ func TestInterpretUInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as UInt256 * 2 as UInt256 - } + fun main() { + let x = 1 as UInt256 * 2 as UInt256 + } ` meter := newTestMemoryGauge() @@ -3451,9 +3456,9 @@ func TestInterpretUInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = (1 as UInt256).saturatingMultiply(2 as UInt256) - } + fun main() { + let x = (1 as UInt256).saturatingMultiply(2 as UInt256) + } ` meter := newTestMemoryGauge() @@ -3472,9 +3477,9 @@ func TestInterpretUInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt256 / 2 as UInt256 - } + fun main() { + let x = 10 as UInt256 / 2 as UInt256 + } ` meter := newTestMemoryGauge() @@ -3493,9 +3498,9 @@ func TestInterpretUInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt256 % 2 as UInt256 - } + fun main() { + let x = 10 as UInt256 % 2 as UInt256 + } ` meter := newTestMemoryGauge() @@ -3514,9 +3519,9 @@ func TestInterpretUInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt256 | 2 as UInt256 - } + fun main() { + let x = 10 as UInt256 | 2 as UInt256 + } ` meter := newTestMemoryGauge() @@ -3535,9 +3540,9 @@ func TestInterpretUInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt256 ^ 2 as UInt256 - } + fun main() { + let x = 10 as UInt256 ^ 2 as UInt256 + } ` meter := newTestMemoryGauge() @@ -3556,9 +3561,9 @@ func TestInterpretUInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt256 & 2 as UInt256 - } + fun main() { + let x = 10 as UInt256 & 2 as UInt256 + } ` meter := newTestMemoryGauge() @@ -3577,9 +3582,9 @@ func TestInterpretUInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt256 << 2 as UInt256 - } + fun main() { + let x = 10 as UInt256 << 2 as UInt256 + } ` meter := newTestMemoryGauge() @@ -3598,9 +3603,9 @@ func TestInterpretUInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as UInt256 >> 2 as UInt256 - } + fun main() { + let x = 10 as UInt256 >> 2 as UInt256 + } ` meter := newTestMemoryGauge() @@ -3624,9 +3629,9 @@ func TestInterpretInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int8 = 1 - } + fun main() { + let x: Int8 = 1 + } ` meter := newTestMemoryGauge() @@ -3643,9 +3648,9 @@ func TestInterpretInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int8 = 1 + 2 - } + fun main() { + let x: Int8 = 1 + 2 + } ` meter := newTestMemoryGauge() @@ -3664,10 +3669,10 @@ func TestInterpretInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int8 = 1 - let y: Int8 = x.saturatingAdd(2) - } + fun main() { + let x: Int8 = 1 + let y: Int8 = x.saturatingAdd(2) + } ` meter := newTestMemoryGauge() @@ -3686,9 +3691,9 @@ func TestInterpretInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int8 = 1 - 2 - } + fun main() { + let x: Int8 = 1 - 2 + } ` meter := newTestMemoryGauge() @@ -3707,10 +3712,10 @@ func TestInterpretInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int8 = 1 - let y: Int8 = x.saturatingSubtract(2) - } + fun main() { + let x: Int8 = 1 + let y: Int8 = x.saturatingSubtract(2) + } ` meter := newTestMemoryGauge() @@ -3729,9 +3734,9 @@ func TestInterpretInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int8 = 1 * 2 - } + fun main() { + let x: Int8 = 1 * 2 + } ` meter := newTestMemoryGauge() @@ -3750,10 +3755,10 @@ func TestInterpretInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int8 = 1 - let y: Int8 = x.saturatingMultiply(2) - } + fun main() { + let x: Int8 = 1 + let y: Int8 = x.saturatingMultiply(2) + } ` meter := newTestMemoryGauge() @@ -3772,9 +3777,9 @@ func TestInterpretInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int8 = 3 / 2 - } + fun main() { + let x: Int8 = 3 / 2 + } ` meter := newTestMemoryGauge() @@ -3793,10 +3798,10 @@ func TestInterpretInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int8 = 3 - let y: Int8 = x.saturatingMultiply(2) - } + fun main() { + let x: Int8 = 3 + let y: Int8 = x.saturatingMultiply(2) + } ` meter := newTestMemoryGauge() @@ -3815,9 +3820,9 @@ func TestInterpretInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int8 = 3 % 2 - } + fun main() { + let x: Int8 = 3 % 2 + } ` meter := newTestMemoryGauge() @@ -3836,10 +3841,10 @@ func TestInterpretInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int8 = 1 - let y: Int8 = -x - } + fun main() { + let x: Int8 = 1 + let y: Int8 = -x + } ` meter := newTestMemoryGauge() @@ -3858,9 +3863,9 @@ func TestInterpretInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int8 = 3 | 2 - } + fun main() { + let x: Int8 = 3 | 2 + } ` meter := newTestMemoryGauge() @@ -3879,9 +3884,9 @@ func TestInterpretInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int8 = 3 ^ 2 - } + fun main() { + let x: Int8 = 3 ^ 2 + } ` meter := newTestMemoryGauge() @@ -3900,9 +3905,9 @@ func TestInterpretInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int8 = 3 & 2 - } + fun main() { + let x: Int8 = 3 & 2 + } ` meter := newTestMemoryGauge() @@ -3921,9 +3926,9 @@ func TestInterpretInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int8 = 3 << 2 - } + fun main() { + let x: Int8 = 3 << 2 + } ` meter := newTestMemoryGauge() @@ -3942,9 +3947,9 @@ func TestInterpretInt8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int8 = 3 >> 2 - } + fun main() { + let x: Int8 = 3 >> 2 + } ` meter := newTestMemoryGauge() @@ -3969,9 +3974,9 @@ func TestInterpretInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int16 = 1 - } + fun main() { + let x: Int16 = 1 + } ` meter := newTestMemoryGauge() @@ -3988,9 +3993,9 @@ func TestInterpretInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int16 = 1 + 2 - } + fun main() { + let x: Int16 = 1 + 2 + } ` meter := newTestMemoryGauge() @@ -4009,10 +4014,10 @@ func TestInterpretInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int16 = 1 - let y: Int16 = x.saturatingAdd(2) - } + fun main() { + let x: Int16 = 1 + let y: Int16 = x.saturatingAdd(2) + } ` meter := newTestMemoryGauge() @@ -4031,9 +4036,9 @@ func TestInterpretInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int16 = 1 - 2 - } + fun main() { + let x: Int16 = 1 - 2 + } ` meter := newTestMemoryGauge() @@ -4052,10 +4057,10 @@ func TestInterpretInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int16 = 1 - let y: Int16 = x.saturatingSubtract(2) - } + fun main() { + let x: Int16 = 1 + let y: Int16 = x.saturatingSubtract(2) + } ` meter := newTestMemoryGauge() @@ -4074,9 +4079,9 @@ func TestInterpretInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int16 = 1 * 2 - } + fun main() { + let x: Int16 = 1 * 2 + } ` meter := newTestMemoryGauge() @@ -4095,10 +4100,10 @@ func TestInterpretInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int16 = 1 - let y: Int16 = x.saturatingMultiply(2) - } + fun main() { + let x: Int16 = 1 + let y: Int16 = x.saturatingMultiply(2) + } ` meter := newTestMemoryGauge() @@ -4117,9 +4122,9 @@ func TestInterpretInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int16 = 3 / 2 - } + fun main() { + let x: Int16 = 3 / 2 + } ` meter := newTestMemoryGauge() @@ -4138,10 +4143,10 @@ func TestInterpretInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int16 = 3 - let y: Int16 = x.saturatingMultiply(2) - } + fun main() { + let x: Int16 = 3 + let y: Int16 = x.saturatingMultiply(2) + } ` meter := newTestMemoryGauge() @@ -4160,9 +4165,9 @@ func TestInterpretInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int16 = 3 % 2 - } + fun main() { + let x: Int16 = 3 % 2 + } ` meter := newTestMemoryGauge() @@ -4181,10 +4186,10 @@ func TestInterpretInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int16 = 1 - let y: Int16 = -x - } + fun main() { + let x: Int16 = 1 + let y: Int16 = -x + } ` meter := newTestMemoryGauge() @@ -4203,9 +4208,9 @@ func TestInterpretInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int16 = 3 | 2 - } + fun main() { + let x: Int16 = 3 | 2 + } ` meter := newTestMemoryGauge() @@ -4224,9 +4229,9 @@ func TestInterpretInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int16 = 3 ^ 2 - } + fun main() { + let x: Int16 = 3 ^ 2 + } ` meter := newTestMemoryGauge() @@ -4245,9 +4250,9 @@ func TestInterpretInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int16 = 3 & 2 - } + fun main() { + let x: Int16 = 3 & 2 + } ` meter := newTestMemoryGauge() @@ -4266,9 +4271,9 @@ func TestInterpretInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int16 = 3 << 2 - } + fun main() { + let x: Int16 = 3 << 2 + } ` meter := newTestMemoryGauge() @@ -4287,9 +4292,9 @@ func TestInterpretInt16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int16 = 3 >> 2 - } + fun main() { + let x: Int16 = 3 >> 2 + } ` meter := newTestMemoryGauge() @@ -4313,9 +4318,9 @@ func TestInterpretInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int32 = 1 - } + fun main() { + let x: Int32 = 1 + } ` meter := newTestMemoryGauge() @@ -4332,9 +4337,9 @@ func TestInterpretInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int32 = 1 + 2 - } + fun main() { + let x: Int32 = 1 + 2 + } ` meter := newTestMemoryGauge() @@ -4353,10 +4358,10 @@ func TestInterpretInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int32 = 1 - let y: Int32 = x.saturatingAdd(2) - } + fun main() { + let x: Int32 = 1 + let y: Int32 = x.saturatingAdd(2) + } ` meter := newTestMemoryGauge() @@ -4375,9 +4380,9 @@ func TestInterpretInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int32 = 1 - 2 - } + fun main() { + let x: Int32 = 1 - 2 + } ` meter := newTestMemoryGauge() @@ -4396,10 +4401,10 @@ func TestInterpretInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int32 = 1 - let y: Int32 = x.saturatingSubtract(2) - } + fun main() { + let x: Int32 = 1 + let y: Int32 = x.saturatingSubtract(2) + } ` meter := newTestMemoryGauge() @@ -4418,9 +4423,9 @@ func TestInterpretInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int32 = 1 * 2 - } + fun main() { + let x: Int32 = 1 * 2 + } ` meter := newTestMemoryGauge() @@ -4439,10 +4444,10 @@ func TestInterpretInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int32 = 1 - let y: Int32 = x.saturatingMultiply(2) - } + fun main() { + let x: Int32 = 1 + let y: Int32 = x.saturatingMultiply(2) + } ` meter := newTestMemoryGauge() @@ -4461,9 +4466,9 @@ func TestInterpretInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int32 = 3 / 2 - } + fun main() { + let x: Int32 = 3 / 2 + } ` meter := newTestMemoryGauge() @@ -4482,10 +4487,10 @@ func TestInterpretInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int32 = 3 - let y: Int32 = x.saturatingMultiply(2) - } + fun main() { + let x: Int32 = 3 + let y: Int32 = x.saturatingMultiply(2) + } ` meter := newTestMemoryGauge() @@ -4504,9 +4509,9 @@ func TestInterpretInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int32 = 3 % 2 - } + fun main() { + let x: Int32 = 3 % 2 + } ` meter := newTestMemoryGauge() @@ -4525,10 +4530,10 @@ func TestInterpretInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int32 = 1 - let y: Int32 = -x - } + fun main() { + let x: Int32 = 1 + let y: Int32 = -x + } ` meter := newTestMemoryGauge() @@ -4547,9 +4552,9 @@ func TestInterpretInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int32 = 3 | 2 - } + fun main() { + let x: Int32 = 3 | 2 + } ` meter := newTestMemoryGauge() @@ -4568,9 +4573,9 @@ func TestInterpretInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int32 = 3 ^ 2 - } + fun main() { + let x: Int32 = 3 ^ 2 + } ` meter := newTestMemoryGauge() @@ -4589,9 +4594,9 @@ func TestInterpretInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int32 = 3 & 2 - } + fun main() { + let x: Int32 = 3 & 2 + } ` meter := newTestMemoryGauge() @@ -4610,9 +4615,9 @@ func TestInterpretInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int32 = 3 << 2 - } + fun main() { + let x: Int32 = 3 << 2 + } ` meter := newTestMemoryGauge() @@ -4631,9 +4636,9 @@ func TestInterpretInt32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int32 = 3 >> 2 - } + fun main() { + let x: Int32 = 3 >> 2 + } ` meter := newTestMemoryGauge() @@ -4657,9 +4662,9 @@ func TestInterpretInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int64 = 1 - } + fun main() { + let x: Int64 = 1 + } ` meter := newTestMemoryGauge() @@ -4676,9 +4681,9 @@ func TestInterpretInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int64 = 1 + 2 - } + fun main() { + let x: Int64 = 1 + 2 + } ` meter := newTestMemoryGauge() @@ -4697,10 +4702,10 @@ func TestInterpretInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int64 = 1 - let y: Int64 = x.saturatingAdd(2) - } + fun main() { + let x: Int64 = 1 + let y: Int64 = x.saturatingAdd(2) + } ` meter := newTestMemoryGauge() @@ -4719,9 +4724,9 @@ func TestInterpretInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int64 = 1 - 2 - } + fun main() { + let x: Int64 = 1 - 2 + } ` meter := newTestMemoryGauge() @@ -4740,10 +4745,10 @@ func TestInterpretInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int64 = 1 - let y: Int64 = x.saturatingSubtract(2) - } + fun main() { + let x: Int64 = 1 + let y: Int64 = x.saturatingSubtract(2) + } ` meter := newTestMemoryGauge() @@ -4762,9 +4767,9 @@ func TestInterpretInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int64 = 1 * 2 - } + fun main() { + let x: Int64 = 1 * 2 + } ` meter := newTestMemoryGauge() @@ -4783,10 +4788,10 @@ func TestInterpretInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int64 = 1 - let y: Int64 = x.saturatingMultiply(2) - } + fun main() { + let x: Int64 = 1 + let y: Int64 = x.saturatingMultiply(2) + } ` meter := newTestMemoryGauge() @@ -4805,9 +4810,9 @@ func TestInterpretInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int64 = 3 / 2 - } + fun main() { + let x: Int64 = 3 / 2 + } ` meter := newTestMemoryGauge() @@ -4826,10 +4831,10 @@ func TestInterpretInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int64 = 3 - let y: Int64 = x.saturatingMultiply(2) - } + fun main() { + let x: Int64 = 3 + let y: Int64 = x.saturatingMultiply(2) + } ` meter := newTestMemoryGauge() @@ -4848,9 +4853,9 @@ func TestInterpretInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int64 = 3 % 2 - } + fun main() { + let x: Int64 = 3 % 2 + } ` meter := newTestMemoryGauge() @@ -4869,10 +4874,10 @@ func TestInterpretInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int64 = 1 - let y: Int64 = -x - } + fun main() { + let x: Int64 = 1 + let y: Int64 = -x + } ` meter := newTestMemoryGauge() @@ -4891,9 +4896,9 @@ func TestInterpretInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int64 = 3 | 2 - } + fun main() { + let x: Int64 = 3 | 2 + } ` meter := newTestMemoryGauge() @@ -4912,9 +4917,9 @@ func TestInterpretInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int64 = 3 ^ 2 - } + fun main() { + let x: Int64 = 3 ^ 2 + } ` meter := newTestMemoryGauge() @@ -4933,9 +4938,9 @@ func TestInterpretInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int64 = 3 & 2 - } + fun main() { + let x: Int64 = 3 & 2 + } ` meter := newTestMemoryGauge() @@ -4954,9 +4959,9 @@ func TestInterpretInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int64 = 3 << 2 - } + fun main() { + let x: Int64 = 3 << 2 + } ` meter := newTestMemoryGauge() @@ -4975,9 +4980,9 @@ func TestInterpretInt64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int64 = 3 >> 2 - } + fun main() { + let x: Int64 = 3 >> 2 + } ` meter := newTestMemoryGauge() @@ -5001,9 +5006,9 @@ func TestInterpretInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int128 = 1 - } + fun main() { + let x: Int128 = 1 + } ` meter := newTestMemoryGauge() @@ -5020,9 +5025,9 @@ func TestInterpretInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int128 = 1 + 2 - } + fun main() { + let x: Int128 = 1 + 2 + } ` meter := newTestMemoryGauge() @@ -5041,10 +5046,10 @@ func TestInterpretInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int128 = 1 - let y: Int128 = x.saturatingAdd(2) - } + fun main() { + let x: Int128 = 1 + let y: Int128 = x.saturatingAdd(2) + } ` meter := newTestMemoryGauge() @@ -5063,9 +5068,9 @@ func TestInterpretInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int128 = 1 - 2 - } + fun main() { + let x: Int128 = 1 - 2 + } ` meter := newTestMemoryGauge() @@ -5084,10 +5089,10 @@ func TestInterpretInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int128 = 1 - let y: Int128 = x.saturatingSubtract(2) - } + fun main() { + let x: Int128 = 1 + let y: Int128 = x.saturatingSubtract(2) + } ` meter := newTestMemoryGauge() @@ -5106,9 +5111,9 @@ func TestInterpretInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int128 = 1 * 2 - } + fun main() { + let x: Int128 = 1 * 2 + } ` meter := newTestMemoryGauge() @@ -5127,10 +5132,10 @@ func TestInterpretInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int128 = 1 - let y: Int128 = x.saturatingMultiply(2) - } + fun main() { + let x: Int128 = 1 + let y: Int128 = x.saturatingMultiply(2) + } ` meter := newTestMemoryGauge() @@ -5149,9 +5154,9 @@ func TestInterpretInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int128 = 3 / 2 - } + fun main() { + let x: Int128 = 3 / 2 + } ` meter := newTestMemoryGauge() @@ -5170,10 +5175,10 @@ func TestInterpretInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int128 = 3 - let y: Int128 = x.saturatingMultiply(2) - } + fun main() { + let x: Int128 = 3 + let y: Int128 = x.saturatingMultiply(2) + } ` meter := newTestMemoryGauge() @@ -5192,9 +5197,9 @@ func TestInterpretInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int128 = 3 % 2 - } + fun main() { + let x: Int128 = 3 % 2 + } ` meter := newTestMemoryGauge() @@ -5213,10 +5218,10 @@ func TestInterpretInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int128 = 1 - let y: Int128 = -x - } + fun main() { + let x: Int128 = 1 + let y: Int128 = -x + } ` meter := newTestMemoryGauge() @@ -5235,9 +5240,9 @@ func TestInterpretInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int128 = 3 | 2 - } + fun main() { + let x: Int128 = 3 | 2 + } ` meter := newTestMemoryGauge() @@ -5256,9 +5261,9 @@ func TestInterpretInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int128 = 3 ^ 2 - } + fun main() { + let x: Int128 = 3 ^ 2 + } ` meter := newTestMemoryGauge() @@ -5277,9 +5282,9 @@ func TestInterpretInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int128 = 3 & 2 - } + fun main() { + let x: Int128 = 3 & 2 + } ` meter := newTestMemoryGauge() @@ -5298,9 +5303,9 @@ func TestInterpretInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int128 = 3 << 2 - } + fun main() { + let x: Int128 = 3 << 2 + } ` meter := newTestMemoryGauge() @@ -5319,9 +5324,9 @@ func TestInterpretInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int128 = 3 >> 2 - } + fun main() { + let x: Int128 = 3 >> 2 + } ` meter := newTestMemoryGauge() @@ -5340,15 +5345,15 @@ func TestInterpretInt128Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int128 = 1 - x == 1 - x != 1 - x > 1 - x >= 1 - x < 1 - x <= 1 - } + fun main() { + let x: Int128 = 1 + x == 1 + x != 1 + x > 1 + x >= 1 + x < 1 + x <= 1 + } ` meter := newTestMemoryGauge() @@ -5370,9 +5375,9 @@ func TestInterpretInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int256 = 1 - } + fun main() { + let x: Int256 = 1 + } ` meter := newTestMemoryGauge() @@ -5389,9 +5394,9 @@ func TestInterpretInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int256 = 1 + 2 - } + fun main() { + let x: Int256 = 1 + 2 + } ` meter := newTestMemoryGauge() @@ -5410,10 +5415,10 @@ func TestInterpretInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int256 = 1 - let y: Int256 = x.saturatingAdd(2) - } + fun main() { + let x: Int256 = 1 + let y: Int256 = x.saturatingAdd(2) + } ` meter := newTestMemoryGauge() @@ -5432,9 +5437,9 @@ func TestInterpretInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int256 = 1 - 2 - } + fun main() { + let x: Int256 = 1 - 2 + } ` meter := newTestMemoryGauge() @@ -5453,10 +5458,10 @@ func TestInterpretInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int256 = 1 - let y: Int256 = x.saturatingSubtract(2) - } + fun main() { + let x: Int256 = 1 + let y: Int256 = x.saturatingSubtract(2) + } ` meter := newTestMemoryGauge() @@ -5475,9 +5480,9 @@ func TestInterpretInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int256 = 1 * 2 - } + fun main() { + let x: Int256 = 1 * 2 + } ` meter := newTestMemoryGauge() @@ -5496,10 +5501,10 @@ func TestInterpretInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int256 = 1 - let y: Int256 = x.saturatingMultiply(2) - } + fun main() { + let x: Int256 = 1 + let y: Int256 = x.saturatingMultiply(2) + } ` meter := newTestMemoryGauge() @@ -5518,9 +5523,9 @@ func TestInterpretInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int256 = 3 / 2 - } + fun main() { + let x: Int256 = 3 / 2 + } ` meter := newTestMemoryGauge() @@ -5539,10 +5544,10 @@ func TestInterpretInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int256 = 3 - let y: Int256 = x.saturatingMultiply(2) - } + fun main() { + let x: Int256 = 3 + let y: Int256 = x.saturatingMultiply(2) + } ` meter := newTestMemoryGauge() @@ -5561,9 +5566,9 @@ func TestInterpretInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int256 = 3 % 2 - } + fun main() { + let x: Int256 = 3 % 2 + } ` meter := newTestMemoryGauge() @@ -5582,10 +5587,10 @@ func TestInterpretInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int256 = 1 - let y: Int256 = -x - } + fun main() { + let x: Int256 = 1 + let y: Int256 = -x + } ` meter := newTestMemoryGauge() @@ -5604,9 +5609,9 @@ func TestInterpretInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int256 = 3 | 2 - } + fun main() { + let x: Int256 = 3 | 2 + } ` meter := newTestMemoryGauge() @@ -5625,9 +5630,9 @@ func TestInterpretInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int256 = 3 ^ 2 - } + fun main() { + let x: Int256 = 3 ^ 2 + } ` meter := newTestMemoryGauge() @@ -5646,9 +5651,9 @@ func TestInterpretInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int256 = 3 & 2 - } + fun main() { + let x: Int256 = 3 & 2 + } ` meter := newTestMemoryGauge() @@ -5667,9 +5672,9 @@ func TestInterpretInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int256 = 3 << 2 - } + fun main() { + let x: Int256 = 3 << 2 + } ` meter := newTestMemoryGauge() @@ -5688,9 +5693,9 @@ func TestInterpretInt256Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Int256 = 3 >> 2 - } + fun main() { + let x: Int256 = 3 >> 2 + } ` meter := newTestMemoryGauge() @@ -5714,9 +5719,9 @@ func TestInterpretWord8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as Word8 - } + fun main() { + let x = 1 as Word8 + } ` meter := newTestMemoryGauge() @@ -5735,9 +5740,9 @@ func TestInterpretWord8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as Word8 + 2 as Word8 - } + fun main() { + let x = 1 as Word8 + 2 as Word8 + } ` meter := newTestMemoryGauge() @@ -5756,9 +5761,9 @@ func TestInterpretWord8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 3 as Word8 - 2 as Word8 - } + fun main() { + let x = 3 as Word8 - 2 as Word8 + } ` meter := newTestMemoryGauge() @@ -5777,9 +5782,9 @@ func TestInterpretWord8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as Word8 * 2 as Word8 - } + fun main() { + let x = 1 as Word8 * 2 as Word8 + } ` meter := newTestMemoryGauge() @@ -5798,9 +5803,9 @@ func TestInterpretWord8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word8 / 2 as Word8 - } + fun main() { + let x = 10 as Word8 / 2 as Word8 + } ` meter := newTestMemoryGauge() @@ -5819,9 +5824,9 @@ func TestInterpretWord8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word8 % 2 as Word8 - } + fun main() { + let x = 10 as Word8 % 2 as Word8 + } ` meter := newTestMemoryGauge() @@ -5840,9 +5845,9 @@ func TestInterpretWord8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word8 | 2 as Word8 - } + fun main() { + let x = 10 as Word8 | 2 as Word8 + } ` meter := newTestMemoryGauge() @@ -5861,9 +5866,9 @@ func TestInterpretWord8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word8 ^ 2 as Word8 - } + fun main() { + let x = 10 as Word8 ^ 2 as Word8 + } ` meter := newTestMemoryGauge() @@ -5882,9 +5887,9 @@ func TestInterpretWord8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word8 & 2 as Word8 - } + fun main() { + let x = 10 as Word8 & 2 as Word8 + } ` meter := newTestMemoryGauge() @@ -5903,9 +5908,9 @@ func TestInterpretWord8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word8 << 2 as Word8 - } + fun main() { + let x = 10 as Word8 << 2 as Word8 + } ` meter := newTestMemoryGauge() @@ -5924,9 +5929,9 @@ func TestInterpretWord8Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word8 >> 2 as Word8 - } + fun main() { + let x = 10 as Word8 >> 2 as Word8 + } ` meter := newTestMemoryGauge() @@ -5950,9 +5955,9 @@ func TestInterpretWord16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as Word16 - } + fun main() { + let x = 1 as Word16 + } ` meter := newTestMemoryGauge() @@ -5970,9 +5975,9 @@ func TestInterpretWord16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as Word16 + 2 as Word16 - } + fun main() { + let x = 1 as Word16 + 2 as Word16 + } ` meter := newTestMemoryGauge() @@ -5991,9 +5996,9 @@ func TestInterpretWord16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 3 as Word16 - 2 as Word16 - } + fun main() { + let x = 3 as Word16 - 2 as Word16 + } ` meter := newTestMemoryGauge() @@ -6012,9 +6017,9 @@ func TestInterpretWord16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as Word16 * 2 as Word16 - } + fun main() { + let x = 1 as Word16 * 2 as Word16 + } ` meter := newTestMemoryGauge() @@ -6033,9 +6038,9 @@ func TestInterpretWord16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word16 / 2 as Word16 - } + fun main() { + let x = 10 as Word16 / 2 as Word16 + } ` meter := newTestMemoryGauge() @@ -6054,9 +6059,9 @@ func TestInterpretWord16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word16 % 2 as Word16 - } + fun main() { + let x = 10 as Word16 % 2 as Word16 + } ` meter := newTestMemoryGauge() @@ -6075,9 +6080,9 @@ func TestInterpretWord16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word16 | 2 as Word16 - } + fun main() { + let x = 10 as Word16 | 2 as Word16 + } ` meter := newTestMemoryGauge() @@ -6096,9 +6101,9 @@ func TestInterpretWord16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word16 ^ 2 as Word16 - } + fun main() { + let x = 10 as Word16 ^ 2 as Word16 + } ` meter := newTestMemoryGauge() @@ -6117,9 +6122,9 @@ func TestInterpretWord16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word16 & 2 as Word16 - } + fun main() { + let x = 10 as Word16 & 2 as Word16 + } ` meter := newTestMemoryGauge() @@ -6138,9 +6143,9 @@ func TestInterpretWord16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word16 << 2 as Word16 - } + fun main() { + let x = 10 as Word16 << 2 as Word16 + } ` meter := newTestMemoryGauge() @@ -6159,9 +6164,9 @@ func TestInterpretWord16Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word16 >> 2 as Word16 - } + fun main() { + let x = 10 as Word16 >> 2 as Word16 + } ` meter := newTestMemoryGauge() @@ -6185,9 +6190,9 @@ func TestInterpretWord32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as Word32 - } + fun main() { + let x = 1 as Word32 + } ` meter := newTestMemoryGauge() @@ -6205,9 +6210,9 @@ func TestInterpretWord32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as Word32 + 2 as Word32 - } + fun main() { + let x = 1 as Word32 + 2 as Word32 + } ` meter := newTestMemoryGauge() @@ -6226,9 +6231,9 @@ func TestInterpretWord32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 3 as Word32 - 2 as Word32 - } + fun main() { + let x = 3 as Word32 - 2 as Word32 + } ` meter := newTestMemoryGauge() @@ -6247,9 +6252,9 @@ func TestInterpretWord32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as Word32 * 2 as Word32 - } + fun main() { + let x = 1 as Word32 * 2 as Word32 + } ` meter := newTestMemoryGauge() @@ -6268,9 +6273,9 @@ func TestInterpretWord32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word32 / 2 as Word32 - } + fun main() { + let x = 10 as Word32 / 2 as Word32 + } ` meter := newTestMemoryGauge() @@ -6289,9 +6294,9 @@ func TestInterpretWord32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word32 % 2 as Word32 - } + fun main() { + let x = 10 as Word32 % 2 as Word32 + } ` meter := newTestMemoryGauge() @@ -6310,9 +6315,9 @@ func TestInterpretWord32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word32 | 2 as Word32 - } + fun main() { + let x = 10 as Word32 | 2 as Word32 + } ` meter := newTestMemoryGauge() @@ -6331,9 +6336,9 @@ func TestInterpretWord32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word32 ^ 2 as Word32 - } + fun main() { + let x = 10 as Word32 ^ 2 as Word32 + } ` meter := newTestMemoryGauge() @@ -6352,9 +6357,9 @@ func TestInterpretWord32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word32 & 2 as Word32 - } + fun main() { + let x = 10 as Word32 & 2 as Word32 + } ` meter := newTestMemoryGauge() @@ -6373,9 +6378,9 @@ func TestInterpretWord32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word32 << 2 as Word32 - } + fun main() { + let x = 10 as Word32 << 2 as Word32 + } ` meter := newTestMemoryGauge() @@ -6394,9 +6399,9 @@ func TestInterpretWord32Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word32 >> 2 as Word32 - } + fun main() { + let x = 10 as Word32 >> 2 as Word32 + } ` meter := newTestMemoryGauge() @@ -6420,9 +6425,9 @@ func TestInterpretWord64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as Word64 - } + fun main() { + let x = 1 as Word64 + } ` meter := newTestMemoryGauge() @@ -6440,9 +6445,9 @@ func TestInterpretWord64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as Word64 + 2 as Word64 - } + fun main() { + let x = 1 as Word64 + 2 as Word64 + } ` meter := newTestMemoryGauge() @@ -6461,9 +6466,9 @@ func TestInterpretWord64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 3 as Word64 - 2 as Word64 - } + fun main() { + let x = 3 as Word64 - 2 as Word64 + } ` meter := newTestMemoryGauge() @@ -6482,9 +6487,9 @@ func TestInterpretWord64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 1 as Word64 * 2 as Word64 - } + fun main() { + let x = 1 as Word64 * 2 as Word64 + } ` meter := newTestMemoryGauge() @@ -6503,9 +6508,9 @@ func TestInterpretWord64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word64 / 2 as Word64 - } + fun main() { + let x = 10 as Word64 / 2 as Word64 + } ` meter := newTestMemoryGauge() @@ -6524,9 +6529,9 @@ func TestInterpretWord64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word64 % 2 as Word64 - } + fun main() { + let x = 10 as Word64 % 2 as Word64 + } ` meter := newTestMemoryGauge() @@ -6545,9 +6550,9 @@ func TestInterpretWord64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word64 | 2 as Word64 - } + fun main() { + let x = 10 as Word64 | 2 as Word64 + } ` meter := newTestMemoryGauge() @@ -6566,9 +6571,9 @@ func TestInterpretWord64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word64 ^ 2 as Word64 - } + fun main() { + let x = 10 as Word64 ^ 2 as Word64 + } ` meter := newTestMemoryGauge() @@ -6587,9 +6592,9 @@ func TestInterpretWord64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word64 & 2 as Word64 - } + fun main() { + let x = 10 as Word64 & 2 as Word64 + } ` meter := newTestMemoryGauge() @@ -6608,9 +6613,9 @@ func TestInterpretWord64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word64 << 2 as Word64 - } + fun main() { + let x = 10 as Word64 << 2 as Word64 + } ` meter := newTestMemoryGauge() @@ -6629,9 +6634,9 @@ func TestInterpretWord64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 10 as Word64 >> 2 as Word64 - } + fun main() { + let x = 10 as Word64 >> 2 as Word64 + } ` meter := newTestMemoryGauge() @@ -6653,12 +6658,12 @@ func TestInterpretStorageReferenceValueMetering(t *testing.T) { t.Parallel() script := ` - resource R {} + resource R {} - access(all) fun main(account: auth(Storage) &Account) { - account.storage.borrow<&R>(from: /storage/r) - } - ` + fun main(account: auth(Storage) &Account) { + account.storage.borrow<&R>(from: /storage/r) + } + ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -6692,10 +6697,10 @@ func TestInterpretEphemeralReferenceValueMetering(t *testing.T) { script := ` resource R {} - access(all) fun main(): &Int { - let x: Int = 1 - let y = &x as &Int - return y + fun main(): &Int { + let x: Int = 1 + let y = &x as &Int + return y } ` @@ -6714,10 +6719,10 @@ func TestInterpretEphemeralReferenceValueMetering(t *testing.T) { script := ` resource R {} - access(all) fun main(): &Int { - let x: Int? = 1 - let y = &x as &Int? - return y! + fun main(): &Int { + let x: Int? = 1 + let y = &x as &Int? + return y! } ` @@ -6740,9 +6745,9 @@ func TestInterpretStringMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = "a" - } + fun main() { + let x = "a" + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -6758,10 +6763,10 @@ func TestInterpretStringMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = "a" - let y = x - } + fun main() { + let x = "a" + let y = x + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -6777,9 +6782,9 @@ func TestInterpretStringMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = "İ" - } + fun main() { + let x = "İ" + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -6795,9 +6800,9 @@ func TestInterpretStringMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = "ABC".toLower() - } + fun main() { + let x = "ABC".toLower() + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -6814,9 +6819,9 @@ func TestInterpretStringMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = "İ".toLower() - } + fun main() { + let x = "İ".toLower() + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -6836,9 +6841,9 @@ func TestInterpretCharacterMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Character = "a" - } + fun main() { + let x: Character = "a" + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -6854,10 +6859,10 @@ func TestInterpretCharacterMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Character = "a" - let y = x - } + fun main() { + let x: Character = "a" + let y = x + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -6873,10 +6878,10 @@ func TestInterpretCharacterMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: String = "a" - let y: Character = x[0] - } + fun main() { + let x: String = "a" + let y: Character = x[0] + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -6895,9 +6900,9 @@ func TestInterpretAddressValueMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Address = 0x0 - } + fun main() { + let x: Address = 0x0 + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -6912,9 +6917,9 @@ func TestInterpretAddressValueMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = Address(0x0) - } + fun main() { + let x = Address(0x0) + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -6933,9 +6938,9 @@ func TestInterpretPathValueMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = /public/bar - } + fun main() { + let x = /public/bar + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -6950,9 +6955,9 @@ func TestInterpretPathValueMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = PublicPath(identifier: "bar") - } + fun main() { + let x = PublicPath(identifier: "bar") + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -6985,9 +6990,9 @@ func TestInterpretTypeValueMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let t: Type = Type() - } + fun main() { + let t: Type = Type() + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -7002,9 +7007,9 @@ func TestInterpretTypeValueMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let t: Type = ConstantSizedArrayType(type: Type(), size: 2) - } + fun main() { + let t: Type = ConstantSizedArrayType(type: Type(), size: 2) + } ` meter := newTestMemoryGauge() @@ -7020,10 +7025,10 @@ func TestInterpretTypeValueMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let v = 5 - let t: Type = v.getType() - } + fun main() { + let v = 5 + let t: Type = v.getType() + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -7042,12 +7047,12 @@ func TestInterpretVariableMetering(t *testing.T) { t.Parallel() script := ` - var a = 3 - let b = false + var a = 3 + let b = false - access(all) fun main() { - - } + fun main() { + + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -7062,9 +7067,9 @@ func TestInterpretVariableMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main(a: String, b: Bool) { - - } + fun main(a: String, b: Bool) { + + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -7083,9 +7088,9 @@ func TestInterpretVariableMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - var x = fun (x: String, y: Bool) {} - } + fun main() { + var x = fun (x: String, y: Bool) {} + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -7100,10 +7105,10 @@ func TestInterpretVariableMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - var x = fun (x: String, y: Bool) {} - x("", false) - } + fun main() { + var x = fun (x: String, y: Bool) {} + x("", false) + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -7124,9 +7129,9 @@ func TestInterpretFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Fix64 = 1.4 - } + fun main() { + let x: Fix64 = 1.4 + } ` meter := newTestMemoryGauge() @@ -7144,9 +7149,9 @@ func TestInterpretFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Fix64 = 1.4 + 2.5 - } + fun main() { + let x: Fix64 = 1.4 + 2.5 + } ` meter := newTestMemoryGauge() @@ -7166,10 +7171,10 @@ func TestInterpretFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Fix64 = 1.4 - let y: Fix64 = x.saturatingAdd(2.5) - } + fun main() { + let x: Fix64 = 1.4 + let y: Fix64 = x.saturatingAdd(2.5) + } ` meter := newTestMemoryGauge() @@ -7189,9 +7194,9 @@ func TestInterpretFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Fix64 = 1.4 - 2.5 - } + fun main() { + let x: Fix64 = 1.4 - 2.5 + } ` meter := newTestMemoryGauge() @@ -7211,10 +7216,10 @@ func TestInterpretFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Fix64 = 1.4 - let y: Fix64 = x.saturatingSubtract(2.5) - } + fun main() { + let x: Fix64 = 1.4 + let y: Fix64 = x.saturatingSubtract(2.5) + } ` meter := newTestMemoryGauge() @@ -7234,9 +7239,9 @@ func TestInterpretFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Fix64 = 1.4 * 2.5 - } + fun main() { + let x: Fix64 = 1.4 * 2.5 + } ` meter := newTestMemoryGauge() @@ -7256,10 +7261,10 @@ func TestInterpretFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Fix64 = 1.4 - let y: Fix64 = x.saturatingMultiply(2.5) - } + fun main() { + let x: Fix64 = 1.4 + let y: Fix64 = x.saturatingMultiply(2.5) + } ` meter := newTestMemoryGauge() @@ -7279,9 +7284,9 @@ func TestInterpretFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Fix64 = 3.4 / 2.5 - } + fun main() { + let x: Fix64 = 3.4 / 2.5 + } ` meter := newTestMemoryGauge() @@ -7301,10 +7306,10 @@ func TestInterpretFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Fix64 = 3.4 - let y: Fix64 = x.saturatingMultiply(2.5) - } + fun main() { + let x: Fix64 = 3.4 + let y: Fix64 = x.saturatingMultiply(2.5) + } ` meter := newTestMemoryGauge() @@ -7324,9 +7329,9 @@ func TestInterpretFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Fix64 = 3.4 % 2.5 - } + fun main() { + let x: Fix64 = 3.4 % 2.5 + } ` meter := newTestMemoryGauge() @@ -7349,10 +7354,10 @@ func TestInterpretFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Fix64 = 1.4 - let y: Fix64 = -x - } + fun main() { + let x: Fix64 = 1.4 + let y: Fix64 = -x + } ` meter := newTestMemoryGauge() @@ -7373,9 +7378,9 @@ func TestInterpretFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: FixedPoint = -1.4 - } + fun main() { + let x: FixedPoint = -1.4 + } ` meter := newTestMemoryGauge() @@ -7393,15 +7398,15 @@ func TestInterpretFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Fix64 = 1.0 - x == 1.0 - x != 1.0 - x > 1.0 - x >= 1.0 - x < 1.0 - x <= 1.0 - } + fun main() { + let x: Fix64 = 1.0 + x == 1.0 + x != 1.0 + x > 1.0 + x >= 1.0 + x < 1.0 + x <= 1.0 + } ` meter := newTestMemoryGauge() @@ -7423,9 +7428,9 @@ func TestInterpretUFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: UFix64 = 1.4 - } + fun main() { + let x: UFix64 = 1.4 + } ` meter := newTestMemoryGauge() @@ -7443,9 +7448,9 @@ func TestInterpretUFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: UFix64 = 1.4 + 2.5 - } + fun main() { + let x: UFix64 = 1.4 + 2.5 + } ` meter := newTestMemoryGauge() @@ -7465,10 +7470,10 @@ func TestInterpretUFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: UFix64 = 1.4 - let y: UFix64 = x.saturatingAdd(2.5) - } + fun main() { + let x: UFix64 = 1.4 + let y: UFix64 = x.saturatingAdd(2.5) + } ` meter := newTestMemoryGauge() @@ -7488,9 +7493,9 @@ func TestInterpretUFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: UFix64 = 2.5 - 1.4 - } + fun main() { + let x: UFix64 = 2.5 - 1.4 + } ` meter := newTestMemoryGauge() @@ -7510,10 +7515,10 @@ func TestInterpretUFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: UFix64 = 1.4 - let y: UFix64 = x.saturatingSubtract(2.5) - } + fun main() { + let x: UFix64 = 1.4 + let y: UFix64 = x.saturatingSubtract(2.5) + } ` meter := newTestMemoryGauge() @@ -7533,9 +7538,9 @@ func TestInterpretUFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: UFix64 = 1.4 * 2.5 - } + fun main() { + let x: UFix64 = 1.4 * 2.5 + } ` meter := newTestMemoryGauge() @@ -7555,10 +7560,10 @@ func TestInterpretUFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: UFix64 = 1.4 - let y: UFix64 = x.saturatingMultiply(2.5) - } + fun main() { + let x: UFix64 = 1.4 + let y: UFix64 = x.saturatingMultiply(2.5) + } ` meter := newTestMemoryGauge() @@ -7578,9 +7583,9 @@ func TestInterpretUFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: UFix64 = 3.4 / 2.5 - } + fun main() { + let x: UFix64 = 3.4 / 2.5 + } ` meter := newTestMemoryGauge() @@ -7600,10 +7605,10 @@ func TestInterpretUFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: UFix64 = 3.4 - let y: UFix64 = x.saturatingMultiply(2.5) - } + fun main() { + let x: UFix64 = 3.4 + let y: UFix64 = x.saturatingMultiply(2.5) + } ` meter := newTestMemoryGauge() @@ -7623,9 +7628,9 @@ func TestInterpretUFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: UFix64 = 3.4 % 2.5 - } + fun main() { + let x: UFix64 = 3.4 % 2.5 + } ` meter := newTestMemoryGauge() @@ -7648,9 +7653,9 @@ func TestInterpretUFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: FixedPoint = 1.4 - } + fun main() { + let x: FixedPoint = 1.4 + } ` meter := newTestMemoryGauge() @@ -7668,15 +7673,15 @@ func TestInterpretUFix64Metering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: UFix64 = 1.0 - x == 1.0 - x != 1.0 - x > 1.0 - x >= 1.0 - x < 1.0 - x <= 1.0 - } + fun main() { + let x: UFix64 = 1.0 + x == 1.0 + x != 1.0 + x > 1.0 + x >= 1.0 + x < 1.0 + x <= 1.0 + } ` meter := newTestMemoryGauge() @@ -7696,17 +7701,17 @@ func TestInterpretTokenMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - var x: String = "hello" - } + fun main() { + var x: String = "hello" + } - access(all) struct foo { - var x: Int + struct foo { + var x: Int - init() { - self.x = 4 - } - } + init() { + self.x = 4 + } + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -7714,8 +7719,8 @@ func TestInterpretTokenMetering(t *testing.T) { _, err := inter.Invoke("main") require.NoError(t, err) - assert.Equal(t, uint64(38), meter.getMemory(common.MemoryKindTypeToken)) - assert.Equal(t, uint64(25), meter.getMemory(common.MemoryKindSpaceToken)) + assert.Equal(t, uint64(30), meter.getMemory(common.MemoryKindTypeToken)) + assert.Equal(t, uint64(23), meter.getMemory(common.MemoryKindSpaceToken)) assert.Equal(t, uint64(0), meter.getMemory(common.MemoryKindRawString)) }) @@ -7723,20 +7728,20 @@ func TestInterpretTokenMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - var a: [String] = [] - var b = 4 + 6 - var c = true && false != false - var d = 4 as! AnyStruct - } + fun main() { + var a: [String] = [] + var b = 4 + 6 + var c = true && false != false + var d = 4 as! AnyStruct + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) _, err := inter.Invoke("main") require.NoError(t, err) - assert.Equal(t, uint64(39), meter.getMemory(common.MemoryKindTypeToken)) - assert.Equal(t, uint64(31), meter.getMemory(common.MemoryKindSpaceToken)) + assert.Equal(t, uint64(35), meter.getMemory(common.MemoryKindTypeToken)) + assert.Equal(t, uint64(30), meter.getMemory(common.MemoryKindSpaceToken)) assert.Equal(t, uint64(0), meter.getMemory(common.MemoryKindRawString)) }) @@ -7744,20 +7749,20 @@ func TestInterpretTokenMetering(t *testing.T) { t.Parallel() script := ` - /* first line - second line - */ + /* first line + second line + */ - // single line comment - access(all) fun main() {} + // single line comment + fun main() {} ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) _, err := inter.Invoke("main") require.NoError(t, err) - assert.Equal(t, uint64(14), meter.getMemory(common.MemoryKindTypeToken)) - assert.Equal(t, uint64(7), meter.getMemory(common.MemoryKindSpaceToken)) + assert.Equal(t, uint64(10), meter.getMemory(common.MemoryKindTypeToken)) + assert.Equal(t, uint64(6), meter.getMemory(common.MemoryKindSpaceToken)) assert.Equal(t, uint64(0), meter.getMemory(common.MemoryKindRawString)) }) @@ -7765,21 +7770,21 @@ func TestInterpretTokenMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - var a = 1 - var b = 0b1 - var c = 0o1 - var d = 0x1 - var e = 1.4 - } + fun main() { + var a = 1 + var b = 0b1 + var c = 0o1 + var d = 0x1 + var e = 1.4 + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) _, err := inter.Invoke("main") require.NoError(t, err) - assert.Equal(t, uint64(30), meter.getMemory(common.MemoryKindTypeToken)) - assert.Equal(t, uint64(26), meter.getMemory(common.MemoryKindSpaceToken)) + assert.Equal(t, uint64(26), meter.getMemory(common.MemoryKindTypeToken)) + assert.Equal(t, uint64(25), meter.getMemory(common.MemoryKindSpaceToken)) assert.Equal(t, uint64(0), meter.getMemory(common.MemoryKindRawString)) }) } @@ -7793,11 +7798,11 @@ func TestInterpreterStringLocationMetering(t *testing.T) { // Raw string count with empty location script := ` - struct S {} + struct S {} - access(all) fun main() { - let s = CompositeType("") - } + fun main() { + let s = CompositeType("") + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -7810,11 +7815,11 @@ func TestInterpreterStringLocationMetering(t *testing.T) { // Raw string count with non-empty location script = ` - struct S {} + struct S {} - access(all) fun main() { - let s = CompositeType("S.test.S") - } + fun main() { + let s = CompositeType("S.test.S") + } ` meter = newTestMemoryGauge() @@ -7841,10 +7846,10 @@ func TestInterpretIdentifierMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let foo = 4 - let bar = 5 - } + fun main() { + let foo = 4 + let bar = 5 + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -7860,8 +7865,8 @@ func TestInterpretIdentifierMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main(foo: String, bar: String) { - } + fun main(foo: String, bar: String) { + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -7881,18 +7886,18 @@ func TestInterpretIdentifierMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() {} + fun main() {} - access(all) struct foo { - var x: String - var y: String + struct foo { + var x: String + var y: String - init() { - self.x = "a" - self.y = "b" - } + init() { + self.x = "a" + self.y = "b" + } - access(all) fun bar() {} + fun bar() {} } ` @@ -7908,13 +7913,13 @@ func TestInterpretIdentifierMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { // 2 - 'main', empty-return-type - let foo = ["a", "b"] // 1 - foo.length // 3 - 'foo', 'length', constant field resolver - foo.length // 3 - 'foo', 'length', constant field resolver (not re-used) - foo.removeFirst() // 3 - 'foo', 'removeFirst', function resolver - foo.removeFirst() // 3 - 'foo', 'removeFirst', function resolver (not re-used) - } + fun main() { // 2 - 'main', empty-return-type + let foo = ["a", "b"] // 1 + foo.length // 3 - 'foo', 'length', constant field resolver + foo.length // 3 - 'foo', 'length', constant field resolver (not re-used) + foo.removeFirst() // 3 - 'foo', 'removeFirst', function resolver + foo.removeFirst() // 3 - 'foo', 'removeFirst', function resolver (not re-used) + } ` meter := newTestMemoryGauge() @@ -7934,15 +7939,15 @@ func TestInterpretInterfaceStaticType(t *testing.T) { t.Parallel() script := ` - struct interface I {} + struct interface I {} - access(all) fun main() { - let type = Type<{I}>() + fun main() { + let type = Type<{I}>() - IntersectionType( - types: [type.identifier] - ) - } + IntersectionType( + types: [type.identifier] + ) + } ` meter := newTestMemoryGauge() @@ -7963,9 +7968,9 @@ func TestInterpretFunctionStaticType(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - FunctionType(parameters: [], return: Type()) - } + fun main() { + FunctionType(parameters: [], return: Type()) + } ` meter := newTestMemoryGauge() @@ -7981,11 +7986,11 @@ func TestInterpretFunctionStaticType(t *testing.T) { t.Parallel() script := ` - access(all) fun hello() {} + fun hello() {} - access(all) fun main() { - let a = [hello] - } + fun main() { + let a = [hello] + } ` meter := newTestMemoryGauge() @@ -8001,14 +8006,14 @@ func TestInterpretFunctionStaticType(t *testing.T) { t.Parallel() script := ` - access(all) struct S { - fun naught() {} - } + struct S { + fun naught() {} + } - access(all) fun main() { - let x = S() - let y = x.naught - } + fun main() { + let x = S() + let y = x.naught + } ` meter := newTestMemoryGauge() @@ -8024,14 +8029,14 @@ func TestInterpretFunctionStaticType(t *testing.T) { t.Parallel() script := ` - access(all) struct S { - fun naught() {} - } + struct S { + fun naught() {} + } - access(all) fun main() { - let x = S() - x.naught.isInstance(Type()) - } + fun main() { + let x = S() + x.naught.isInstance(Type()) + } ` meter := newTestMemoryGauge() @@ -8051,16 +8056,16 @@ func TestInterpretASTMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - foo(a: "hello", b: 23) - bar("hello", 23) - } + fun main() { + foo(a: "hello", b: 23) + bar("hello", 23) + } - access(all) fun foo(a: String, b: Int) { - } + fun foo(a: String, b: Int) { + } - access(all) fun bar(_ a: String, _ b: Int) { - } + fun bar(_ a: String, _ b: Int) { + } ` meter := newTestMemoryGauge() inter := parseCheckAndInterpretWithMemoryMetering(t, script, meter) @@ -8073,26 +8078,26 @@ func TestInterpretASTMetering(t *testing.T) { t.Run("blocks", func(t *testing.T) { script := ` - access(all) fun main() { - var i = 0 - if i != 0 { - i = 0 - } - - while i < 2 { - i = i + 1 - } - - var a = "foo" - switch i { - case 1: - a = "foo_1" - case 2: - a = "foo_2" - case 3: - a = "foo_3" - } - } + fun main() { + var i = 0 + if i != 0 { + i = 0 + } + + while i < 2 { + i = i + 1 + } + + var a = "foo" + switch i { + case 1: + a = "foo_1" + case 2: + a = "foo_2" + case 3: + a = "foo_3" + } + } ` meter := newTestMemoryGauge() @@ -8106,51 +8111,51 @@ func TestInterpretASTMetering(t *testing.T) { t.Run("declarations", func(t *testing.T) { script := ` - import Foo from 0x42 + import Foo from 0x42 - access(all) let x = 1 - access(all) var y = 2 + let x = 1 + var y = 2 - access(all) fun main() { - var z = 3 - } + fun main() { + var z = 3 + } - access(all) fun foo(_ x: String, _ y: Int) {} + fun foo(_ x: String, _ y: Int) {} - access(all) struct A { - access(all) var a: String + struct A { + var a: String - init() { - self.a = "hello" - } - } + init() { + self.a = "hello" + } + } - access(all) struct interface B {} + struct interface B {} - access(all) resource C { - let a: Int + resource C { + let a: Int - init() { - self.a = 6 - } - } + init() { + self.a = 6 + } + } - access(all) resource interface D {} + resource interface D {} - access(all) enum E: Int8 { - access(all) case a - access(all) case b - access(all) case c - } + enum E: Int8 { + case a + case b + case c + } - transaction {} + transaction {} - #pragma + #pragma ` importedChecker, err := checker.ParseAndCheckWithOptions(t, ` - access(all) let Foo = 1 + let Foo = 1 `, checker.ParseAndCheckOptions{ Location: utils.ImportedLocation, @@ -8214,47 +8219,47 @@ func TestInterpretASTMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - var a = 5 + fun main() { + var a = 5 - while a < 10 { // while - if a == 5 { // if - a = a + 1 // assignment - continue // continue - } - break // break - } + while a < 10 { // while + if a == 5 { // if + a = a + 1 // assignment + continue // continue + } + break // break + } - foo() // expression statement + foo() // expression statement - for value in [1, 2, 3] {} // for + for value in [1, 2, 3] {} // for - var r1 <- create bar() - var r2 <- create bar() - r1 <-> r2 // swap + var r1 <- create bar() + var r2 <- create bar() + r1 <-> r2 // swap - destroy r1 // expression statement - destroy r2 // expression statement + destroy r1 // expression statement + destroy r2 // expression statement - switch a { // switch - case 1: - a = 2 // assignment - } - } + switch a { // switch + case 1: + a = 2 // assignment + } + } - access(all) fun foo(): Int { - return 5 // return - } + fun foo(): Int { + return 5 // return + } - resource bar {} + resource bar {} - access(all) contract Events { - event FooEvent(x: Int, y: Int) + contract Events { + event FooEvent(x: Int, y: Int) - fun events() { - emit FooEvent(x: 1, y: 2) // emit - } - } + fun events() { + emit FooEvent(x: 1, y: 2) // emit + } + } ` meter := newTestMemoryGauge() @@ -8302,32 +8307,32 @@ func TestInterpretASTMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - var a = 5 // integer expr - var b = 1.2 + 2.3 // binary, fixed-point expr - var c = !true // unary, boolean expr - var d: String? = "hello" // string expr - var e = nil // nil expr - var f: [AnyStruct] = [[], [], []] // array expr - var g: {Int: {Int: AnyStruct}} = {1:{}} // nil expr - var h <- create bar() // create, identifier, invocation - var i = h.baz // member access, identifier x2 - destroy h // destroy - var j = f[0] // index access, identifier, integer - var k = fun() {} // function expr - k() // identifier, invocation - var l = c ? 1 : 2 // conditional, identifier, integer x2 - var m = d as AnyStruct // casting, identifier - var n = &d as &AnyStruct? // reference, casting, identifier - var o = d! // force, identifier - var p = /public/somepath // path - } + fun main() { + var a = 5 // integer expr + var b = 1.2 + 2.3 // binary, fixed-point expr + var c = !true // unary, boolean expr + var d: String? = "hello" // string expr + var e = nil // nil expr + var f: [AnyStruct] = [[], [], []] // array expr + var g: {Int: {Int: AnyStruct}} = {1:{}} // nil expr + var h <- create bar() // create, identifier, invocation + var i = h.baz // member access, identifier x2 + destroy h // destroy + var j = f[0] // index access, identifier, integer + var k = fun() {} // function expr + k() // identifier, invocation + var l = c ? 1 : 2 // conditional, identifier, integer x2 + var m = d as AnyStruct // casting, identifier + var n = &d as &AnyStruct? // reference, casting, identifier + var o = d! // force, identifier + var p = /public/somepath // path + } - resource bar { - let baz: Int - init() { - self.baz = 0x4 - } + resource bar { + let baz: Int + init() { + self.baz = 0x4 + } } ` meter := newTestMemoryGauge() @@ -8366,25 +8371,25 @@ func TestInterpretASTMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - var a: Int = 5 // nominal type - var b: String? = "hello" // optional type - var c: [Int; 2] = [1, 2] // constant sized type - var d: [String] = [] // variable sized type - var e: {Int: String} = {} // dictionary type + fun main() { + var a: Int = 5 // nominal type + var b: String? = "hello" // optional type + var c: [Int; 2] = [1, 2] // constant sized type + var d: [String] = [] // variable sized type + var e: {Int: String} = {} // dictionary type - var f: fun(String):Int = fun(_a: String): Int { // function type - return 1 - } + var f: fun(String):Int = fun(_a: String): Int { // function type + return 1 + } - var g = &a as &Int // reference type - var h: {foo} = bar() // intersection type - var i: Capability<&bar>? = nil // instantiation type - } + var g = &a as &Int // reference type + var h: {foo} = bar() // intersection type + var i: Capability<&bar>? = nil // instantiation type + } - struct interface foo {} + struct interface foo {} - struct bar: foo {} + struct bar: foo {} ` meter := newTestMemoryGauge() @@ -8408,24 +8413,24 @@ func TestInterpretASTMetering(t *testing.T) { t.Run("position info", func(t *testing.T) { script := ` - access(all) let x = 1 - access(all) var y = 2 + let x = 1 + var y = 2 - access(all) fun main() { - var z = 3 - } + fun main() { + var z = 3 + } - access(all) fun foo(_ x: String, _ y: Int) {} + fun foo(_ x: String, _ y: Int) {} - access(all) struct A { - access(all) var a: String + struct A { + var a: String - init() { - self.a = "hello" - } - } + init() { + self.a = "hello" + } + } - access(all) struct interface B {} + struct interface B {} ` meter := newTestMemoryGauge() @@ -8435,20 +8440,20 @@ func TestInterpretASTMetering(t *testing.T) { _, err := inter.Invoke("main") require.NoError(t, err) - assert.Equal(t, uint64(271), meter.getMemory(common.MemoryKindPosition)) - assert.Equal(t, uint64(145), meter.getMemory(common.MemoryKindRange)) + assert.Equal(t, uint64(201), meter.getMemory(common.MemoryKindPosition)) + assert.Equal(t, uint64(110), meter.getMemory(common.MemoryKindRange)) }) t.Run("locations", func(t *testing.T) { script := ` - import A from 0x42 - import B from "string-location" + import A from 0x42 + import B from "string-location" ` importedChecker, err := checker.ParseAndCheckWithOptions(t, ` - access(all) let A = 1 - access(all) let B = 1 + let A = 1 + let B = 1 `, checker.ParseAndCheckOptions{ Location: utils.ImportedLocation, @@ -8499,7 +8504,7 @@ func TestInterpretVariableActivationMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() {} + fun main() {} ` meter := newTestMemoryGauge() @@ -8517,12 +8522,12 @@ func TestInterpretVariableActivationMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - foo(a: "hello", b: 23) - } + fun main() { + foo(a: "hello", b: 23) + } - access(all) fun foo(a: String, b: Int) { - } + fun foo(a: String, b: Int) { + } ` meter := newTestMemoryGauge() @@ -8540,11 +8545,11 @@ func TestInterpretVariableActivationMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - if true { - let a = 1 - } - } + fun main() { + if true { + let a = 1 + } + } ` meter := newTestMemoryGauge() @@ -8565,16 +8570,16 @@ func TestInterpretStaticTypeConversionMetering(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let a: {Int: {Foo}} = {} // dictionary + intersection - let b: [&Int] = [] // variable-sized + reference - let c: [Int?; 2] = [1, 2] // constant-sized + optional - let d: [Capability<&Bar>] = [] // capability + variable-sized + reference - } + fun main() { + let a: {Int: {Foo}} = {} // dictionary + intersection + let b: [&Int] = [] // variable-sized + reference + let c: [Int?; 2] = [1, 2] // constant-sized + optional + let d: [Capability<&Bar>] = [] // capability + variable-sized + reference + } - access(all) struct interface Foo {} + struct interface Foo {} - access(all) struct Bar: Foo {} + struct Bar: Foo {} ` meter := newTestMemoryGauge() @@ -8597,12 +8602,12 @@ func TestInterpretStorageMapMetering(t *testing.T) { t.Parallel() script := ` - resource R {} + resource R {} - access(all) fun main(account: auth(Storage) &Account) { - let r <- create R() - account.storage.save(<-r, to: /storage/r) - } + fun main(account: auth(Storage) &Account) { + let r <- create R() + account.storage.save(<-r, to: /storage/r) + } ` meter := newTestMemoryGauge() @@ -8840,11 +8845,11 @@ func TestInterpretValueStringConversion(t *testing.T) { t.Parallel() script := fmt.Sprintf(` - access(all) fun main() { - let x = %s - log(x) - } - `, + fun main() { + let x = %s + log(x) + } + `, test.constructor, ) @@ -8861,17 +8866,17 @@ func TestInterpretValueStringConversion(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = Foo() - log(x) - } + fun main() { + let x = Foo() + log(x) + } - struct Foo { - var a: Word8 - init() { - self.a = 4 - } - } + struct Foo { + var a: Word8 + init() { + self.a = 4 + } + } ` testValueStringConversion(t, script) @@ -8881,10 +8886,10 @@ func TestInterpretValueStringConversion(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = 4 - log(&x as &AnyStruct) - } + fun main() { + let x = 4 + log(&x as &AnyStruct) + } ` testValueStringConversion(t, script) @@ -8894,10 +8899,10 @@ func TestInterpretValueStringConversion(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = fun(a: String, b: Bool) {} - log(&x as &AnyStruct) - } + fun main() { + let x = fun(a: String, b: Bool) {} + log(&x as &AnyStruct) + } ` testValueStringConversion(t, script) @@ -8907,14 +8912,14 @@ func TestInterpretValueStringConversion(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x = Foo() - log(x.bar) - } + fun main() { + let x = Foo() + log(x.bar) + } - struct Foo { - access(all) fun bar(a: String, b: Bool) {} - } + struct Foo { + fun bar(a: String, b: Bool) {} + } ` testValueStringConversion(t, script) @@ -8924,12 +8929,12 @@ func TestInterpretValueStringConversion(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - let x: Void = foo() - log(x) - } + fun main() { + let x: Void = foo() + log(x) + } - fun foo() {} + fun foo() {} ` testValueStringConversion(t, script) @@ -8939,12 +8944,12 @@ func TestInterpretValueStringConversion(t *testing.T) { t.Parallel() script := ` - access(all) fun main(a: Capability<&{Foo}>) { - log(a) - } + fun main(a: Capability<&{Foo}>) { + log(a) + } - struct interface Foo {} - struct Bar: Foo {} + struct interface Foo {} + struct Bar: Foo {} ` testValueStringConversion(t, @@ -8960,9 +8965,9 @@ func TestInterpretValueStringConversion(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - log(Type()) - } + fun main() { + log(Type()) + } ` testValueStringConversion(t, script) @@ -9054,10 +9059,12 @@ func TestInterpretStaticTypeStringConversion(t *testing.T) { continue } - script := fmt.Sprintf(` - access(all) fun main() { - log(Type<%s>()) - }`, + script := fmt.Sprintf( + ` + fun main() { + log(Type<%s>()) + } + `, sema.NewTypeAnnotation(semaType).QualifiedString(), ) @@ -9114,8 +9121,8 @@ func TestInterpretStaticTypeStringConversion(t *testing.T) { t.Parallel() script := fmt.Sprintf(` - entitlement X - access(all) fun main() { + entitlement X + fun main() { log(Type<%s>()) } `, @@ -9135,16 +9142,16 @@ func TestInterpretStaticTypeStringConversion(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - log(Type()) - } + fun main() { + log(Type()) + } - struct Foo { - var a: Word8 - init() { - self.a = 4 - } - } + struct Foo { + var a: Word8 + init() { + self.a = 4 + } + } ` testStaticTypeStringConversion(t, script) @@ -9154,11 +9161,11 @@ func TestInterpretStaticTypeStringConversion(t *testing.T) { t.Parallel() script := ` - access(all) fun main() { - log(Type<{Foo}>()) - } + fun main() { + log(Type<{Foo}>()) + } - struct interface Foo {} + struct interface Foo {} ` testStaticTypeStringConversion(t, script) @@ -9170,9 +9177,9 @@ func TestInterpretBytesMetering(t *testing.T) { t.Parallel() const code = ` - fun test(string: String) { - let utf8 = string.utf8 - } + fun test(string: String) { + let utf8 = string.utf8 + } ` meter := newTestMemoryGauge() diff --git a/runtime/tests/interpreter/string_test.go b/runtime/tests/interpreter/string_test.go index 51873a5a79..37bba83186 100644 --- a/runtime/tests/interpreter/string_test.go +++ b/runtime/tests/interpreter/string_test.go @@ -499,3 +499,100 @@ func TestInterpretStringJoin(t *testing.T) { testCase(t, "testEmptyArray", interpreter.NewUnmeteredStringValue("")) testCase(t, "testSingletonArray", interpreter.NewUnmeteredStringValue("pqrS")) } + +func TestInterpretStringSplit(t *testing.T) { + + t.Parallel() + + inter := parseCheckAndInterpret(t, ` + fun split(): [String] { + return "👪////❤️".split(separator: "////") + } + fun splitBySpace(): [String] { + return "👪 ❤️ Abc6 ;123".split(separator: " ") + } + fun splitWithUnicodeEquivalence(): [String] { + return "Caf\u{65}\u{301}ABc".split(separator: "\u{e9}") + } + fun testEmptyString(): [String] { + return "".split(separator: "//") + } + fun testNoMatch(): [String] { + return "pqrS;asdf".split(separator: ";;") + } + `) + + testCase := func(t *testing.T, funcName string, expected *interpreter.ArrayValue) { + t.Run(funcName, func(t *testing.T) { + result, err := inter.Invoke(funcName) + require.NoError(t, err) + + RequireValuesEqual( + t, + inter, + expected, + result, + ) + }) + } + + varSizedStringType := &interpreter.VariableSizedStaticType{ + Type: interpreter.PrimitiveStaticTypeString, + } + + testCase(t, + "split", + interpreter.NewArrayValue( + inter, + interpreter.EmptyLocationRange, + varSizedStringType, + common.ZeroAddress, + interpreter.NewUnmeteredStringValue("👪"), + interpreter.NewUnmeteredStringValue("❤️"), + ), + ) + testCase(t, + "splitBySpace", + interpreter.NewArrayValue( + inter, + interpreter.EmptyLocationRange, + varSizedStringType, + common.ZeroAddress, + interpreter.NewUnmeteredStringValue("👪"), + interpreter.NewUnmeteredStringValue("❤️"), + interpreter.NewUnmeteredStringValue("Abc6"), + interpreter.NewUnmeteredStringValue(";123"), + ), + ) + testCase(t, + "splitWithUnicodeEquivalence", + interpreter.NewArrayValue( + inter, + interpreter.EmptyLocationRange, + varSizedStringType, + common.ZeroAddress, + interpreter.NewUnmeteredStringValue("Caf"), + interpreter.NewUnmeteredStringValue("ABc"), + ), + ) + testCase(t, + "testEmptyString", + interpreter.NewArrayValue( + inter, + interpreter.EmptyLocationRange, + varSizedStringType, + common.ZeroAddress, + interpreter.NewUnmeteredStringValue(""), + ), + ) + testCase(t, + "testNoMatch", + interpreter.NewArrayValue( + inter, + interpreter.EmptyLocationRange, + varSizedStringType, + common.ZeroAddress, + interpreter.NewUnmeteredStringValue("pqrS;asdf"), + ), + ) +} diff --git a/runtime/tests/utils/utils.go b/runtime/tests/utils/utils.go index ce62a55b81..eb581635a8 100644 --- a/runtime/tests/utils/utils.go +++ b/runtime/tests/utils/utils.go @@ -24,8 +24,8 @@ import ( "strings" "testing" - "github.com/go-test/deep" "github.com/k0kubun/pp" + "github.com/kr/pretty" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -50,38 +50,36 @@ const ImportedLocation = common.StringLocation("imported") // // If the objects are not equal, this function prints a human-readable diff. func AssertEqualWithDiff(t *testing.T, expected, actual any) { - if !assert.Equal(t, expected, actual) { - // the maximum levels of a struct to recurse into - // this prevents infinite recursion from circular references - deep.MaxDepth = 100 - diff := deep.Equal(expected, actual) + // the maximum levels of a struct to recurse into + // this prevents infinite recursion from circular references + diff := pretty.Diff(expected, actual) - if len(diff) != 0 { - s := strings.Builder{} - - for i, d := range diff { - if i == 0 { - s.WriteString("diff : ") - } else { - s.WriteString(" ") - } + if len(diff) != 0 { + s := strings.Builder{} - s.WriteString(d) - s.WriteString("\n") + for i, d := range diff { + if i == 0 { + s.WriteString("diff : ") + } else { + s.WriteString(" ") } - t.Errorf( - "Not equal: \n"+ - "expected: %s\n"+ - "actual : %s\n\n"+ - "%s", - pp.Sprint(expected), - pp.Sprint(actual), - s.String(), - ) + s.WriteString(d) + s.WriteString("\n") } + + t.Errorf( + "Not equal: \n"+ + "expected: %s\n"+ + "actual : %s\n\n"+ + "%s", + pp.Sprint(expected), + pp.Sprint(actual), + s.String(), + ) } + } func AsInterfaceType(name string, kind common.CompositeKind) string { @@ -151,11 +149,11 @@ func ValuesAreEqual(inter *interpreter.Interpreter, expected, actual interpreter func AssertValuesEqual(t testing.TB, interpreter *interpreter.Interpreter, expected, actual interpreter.Value) bool { if !ValuesAreEqual(interpreter, expected, actual) { - diff := deep.Equal(expected, actual) + diff := pretty.Diff(expected, actual) var message string - if len(diff) != 0 { + if len(diff) > 0 { s := strings.Builder{} _, _ = fmt.Fprintf(&s, "Not equal: \n"+ diff --git a/tools/compare-parsing/main.go b/tools/compare-parsing/main.go index 9de50d73c7..36ea0cfab5 100644 --- a/tools/compare-parsing/main.go +++ b/tools/compare-parsing/main.go @@ -35,7 +35,7 @@ import ( "path" "strings" - "github.com/go-test/deep" + "github.com/kr/pretty" ) func main() { @@ -115,13 +115,9 @@ func compareParsing(directory string, location string, code string, parseOld str return } - // the maximum levels of a struct to recurse into - // this prevents infinite recursion from circular references - deep.MaxDepth = 100 + diff := pretty.Diff(res1, res2) - diff := deep.Equal(res1, res2) - - if len(diff) != 0 { + if len(diff) > 0 { var s strings.Builder for _, d := range diff {