diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml
index 023e926059..3ce911b5a0 100644
--- a/.github/workflows/benchmark.yml
+++ b/.github/workflows/benchmark.yml
@@ -45,7 +45,7 @@ jobs:
cache: true
- name: Build
- run: make build
+ run: make -j8 build
- name: Run benchmark on current branch
run: |
@@ -85,14 +85,14 @@ jobs:
This branch with compared with the base branch ${{ github.event.pull_request.base.label }} commit ${{ github.event.pull_request.base.sha }}
The command `for i in {1..N}; do go test ./... -run=XXX -bench=. -benchmem -shuffle=on; done` was used.
Bench tests were run a total of ${{ steps.settings.outputs.benchmark_repetitions }} times on each branch.
-
+
Collapsed results for better readability
${{ env.BENCHSTAT }}
-
+
-
+
edit-mode: replace
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 5ffe55f37d..9601b694a2 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -40,10 +40,10 @@ jobs:
cache: true
- name: Build
- run: make build
+ run: make -j8 build
- name: Test
- run: make test
+ run: make ci
- name: Upload coverage report
uses: codecov/codecov-action@v2
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index f3bedbed81..b51740600f 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -57,7 +57,7 @@ jobs:
- name: Run Tests
run: |
- make test
+ make ci
make lint-github-actions
- name: Config git
diff --git a/Makefile b/Makefile
index e954fbdd5f..5e588c85a1 100644
--- a/Makefile
+++ b/Makefile
@@ -29,32 +29,45 @@ ifneq ($(linters),)
LINTERS = -E $(linters)
endif
+.PHONY: build
+build: build-tools ./runtime/cmd/parse/parse ./runtime/cmd/parse/parse.wasm ./runtime/cmd/check/check ./runtime/cmd/main/main
-.PHONY: test
-test:
+./runtime/cmd/parse/parse:
+ go build -o $@ ./runtime/cmd/parse
+
+./runtime/cmd/parse/parse.wasm:
+ GOARCH=wasm GOOS=js go build -o $@ ./runtime/cmd/parse
+
+./runtime/cmd/check/check:
+ go build -o $@ ./runtime/cmd/check
+
+./runtime/cmd/main/main:
+ go build -o $@ ./runtime/cmd/main
+
+.PHONY: build-tools
+build-tools: build-analysis build-batch-script
+
+.PHONY: build-analysis
+build-analysis:
+ (cd ./tools/analysis && go build .)
+
+.PHONY: build-batch-script
+build-batch-script:
+ (cd ./tools/batch-script && go build .)
+
+.PHONY: ci
+ci:
# test all packages
- GO111MODULE=on go test -coverprofile=coverage.txt -covermode=atomic -parallel 8 -race -coverpkg $(COVERPKGS) ./...
+ go test -coverprofile=coverage.txt -covermode=atomic -parallel 8 -race -coverpkg $(COVERPKGS) ./...
+ # run interpreter smoke tests. results from run above are reused, so no tests runs are duplicated
+ go test -count=5 ./runtime/tests/interpreter/... -runSmokeTests=true -validateAtree=false
# remove coverage of empty functions from report
sed -i -e 's/^.* 0 0$$//' coverage.txt
-.PHONY: fast-test
-fast-test:
+.PHONY: test
+test:
# test all packages
- GO111MODULE=on go test -parallel 8 ./...
-
-.PHONY: build
-build:
- go build -o ./runtime/cmd/parse/parse ./runtime/cmd/parse
- GOARCH=wasm GOOS=js go build -o ./runtime/cmd/parse/parse.wasm ./runtime/cmd/parse
- go build -o ./runtime/cmd/check/check ./runtime/cmd/check
- go build -o ./runtime/cmd/main/main ./runtime/cmd/main
- make build-tools
-
-.PHONY: build-tools
-build-tools:
- (cd ./tools/analysis && go build . && cd -)
- (cd ./tools/batch-script && go build . && cd -)
- (cd ./tools/constructorcheck && make plugin && cd -)
+ go test -parallel 8 ./...
.PHONY: lint-github-actions
lint-github-actions: build-linter
@@ -64,7 +77,6 @@ lint-github-actions: build-linter
lint: build-linter
tools/golangci-lint/golangci-lint run $(LINTERS) --timeout=5m -v ./...
-
.PHONY: fix-lint
fix-lint: build-linter
tools/golangci-lint/golangci-lint run -v --fix --timeout=5m $(LINTERS) ./...
@@ -73,13 +85,13 @@ fix-lint: build-linter
build-linter: tools/golangci-lint/golangci-lint tools/maprange/maprange.so tools/unkeyed/unkeyed.so tools/constructorcheck/constructorcheck.so
tools/maprange/maprange.so:
- (cd tools/maprange && $(MAKE) plugin)
+ (cd tools/maprange && $(MAKE))
tools/unkeyed/unkeyed.so:
- (cd tools/unkeyed && $(MAKE) plugin)
+ (cd tools/unkeyed && $(MAKE))
tools/constructorcheck/constructorcheck.so:
- (cd tools/constructorcheck && $(MAKE) plugin)
+ (cd tools/constructorcheck && $(MAKE))
tools/golangci-lint/golangci-lint:
(cd tools/golangci-lint && $(MAKE))
diff --git a/docs/images/create_release.png b/docs/images/create_release.png
new file mode 100644
index 0000000000..586e83649d
Binary files /dev/null and b/docs/images/create_release.png differ
diff --git a/docs/images/release_action.png b/docs/images/release_action.png
index d46e23a992..30a4559e40 100644
Binary files a/docs/images/release_action.png and b/docs/images/release_action.png differ
diff --git a/docs/images/release_tag.png b/docs/images/release_tag.png
new file mode 100644
index 0000000000..3330f27d2f
Binary files /dev/null and b/docs/images/release_tag.png differ
diff --git a/docs/language/accounts.mdx b/docs/language/accounts.mdx
index 74a00e3f58..b70c84a58b 100644
--- a/docs/language/accounts.mdx
+++ b/docs/language/accounts.mdx
@@ -124,6 +124,7 @@ to the `prepare` phase of the transaction.
fun borrow(from: StoragePath): T?
fun link(_ newCapabilityPath: CapabilityPath, target: Path): Capability?
+ fun linkAccount(_ newCapabilityPath: PrivatePath): Capability<&AuthAccount>?
fun getCapability(_ path: CapabilityPath): Capability
fun getLinkTarget(_ path: CapabilityPath): Path?
fun unlink(_ path: CapabilityPath)
diff --git a/docs/language/attachments.md b/docs/language/attachments.md
index 2e2c03c344..223e942741 100644
--- a/docs/language/attachments.md
+++ b/docs/language/attachments.md
@@ -4,7 +4,7 @@ title: Attachments
⚠️ This section describes a feature that is not yet released on Mainnet.
-It will be available following the next Mainnet Spork.
+It will be deployed to Testnet in its next major upgrade.
Attachments are a feature of Cadence designed to allow developers to extend a struct or resource type
diff --git a/docs/language/built-in-functions.mdx b/docs/language/built-in-functions.mdx
index 8c1b87655e..52f18790f1 100644
--- a/docs/language/built-in-functions.mdx
+++ b/docs/language/built-in-functions.mdx
@@ -37,10 +37,30 @@ fun unsafeRandom(): UInt64
Returns a pseudo-random number.
- NOTE: The use of this function is unsafe if not used correctly.
+ NOTE:
+ Smart contract developers should be mindful about the limitations of unsafeRandom.
+ The stream of random numbers produced is potentially unsafe in the following two regards:
+
+ 1. The sequence of random numbers is potentially predictable by transactions within the same block
+ and by other smart contracts calling into your smart contract.
+ 2. A transaction calling into your smart contract can potentially bias the sequence of random numbers which
+ your smart contract internally generates.
+
+ We are working towards removing these limitations incrementally. Once these points are addressed,
+ Flow’s randomness is safe and we will remove the "unsafe" qualifier.
+
+ Nevertheless, there is an additional safety-relevant aspect that developers need to be mindful about:
+
+ * A transaction can atomically revert all its action at any time. Therefore, it is possible for a transaction calling into
+ your smart contract to post-select favourable results and revert the transaction for unfavourable results.
+ ([example](https://consensys.github.io/smart-contract-best-practices/development-recommendations/general/public-data/))
+
+ This limitation is inherent to any smart contract platform that allows transactions to roll back atomically and cannot be
+ solved through safe randomness alone. Providing additional Cadence language primitives to simplify this challenge for
+ developers is on our roadmap as well. Nevertheless, with safe randomness (points 1 and 2 above resolved), developers can prevent
+ clients from post-select favourable outcomes using approaches such as described in the
+ [example](https://consensys.github.io/smart-contract-best-practices/development-recommendations/general/public-data/).
- Follow [best practices](https://consensys.github.io/smart-contract-best-practices/development-recommendations/general/public-data/)
- to prevent security issues when using this function.
## RLP
diff --git a/docs/language/run-time-types.md b/docs/language/run-time-types.md
index f0d8306902..45fca64450 100644
--- a/docs/language/run-time-types.md
+++ b/docs/language/run-time-types.md
@@ -93,7 +93,7 @@ fun InterfaceType(_ identifier: String): Type?
fun RestrictedType(identifier: String?, restrictions: [String]): Type?
```
-Given a type identifer (as well as a list of identifiers for restricting interfaces
+Given a type identifier (as well as a list of identifiers for restricting interfaces
in the case of `RestrictedType`), these functions will look up nominal types and
produce their run-time equivalents. If the provided identifiers do not correspond
to any types, or (in the case of `RestrictedType`) the provided combination of
diff --git a/docs/releasing.md b/docs/releasing.md
index a1bd423c88..7edfcde625 100644
--- a/docs/releasing.md
+++ b/docs/releasing.md
@@ -1,6 +1,6 @@
# Release Process
-Assume releasing Cadence version `v0.21.2` from `master` branch.
+Assume releasing Cadence version `v0.21.2` from `master` branch.
Also, assume the latest deployed version on the live networks is `v0.21.0`.
## Using GitHub Actions
@@ -20,10 +20,10 @@ Check for breaking changes can be done using the [BackwardCompatibilityCheck](ht
github action.
-
+
Run the workflow by providing `master` as the `Current branch/tag` and `v0.21.0` which is the latest deployed version
on the live networks, as the `Base branch/tag`.
-Since the release would be based on the current master branch, the compatibility check would compare the current `master`
+Since the release would be based on the current master branch, the compatibility check would compare the current `master`
branch against `v0.21.0` branch/tag.
@@ -129,3 +129,24 @@ If it is deemed that there are no breaking changes, proceed to the [Releasing](#
```
- Finally, open a PR from `release/v0.21.2` branch to the base branch (`master` in this case),
to include the version bump changes.
+
+
+## Creating a new GitHub release
+
+Once the PR which updates the version got merged, a GitHub release can be created.
+
+Go to the overview of all tags and select "Create release":
+
+
+
+On the release page, click the "Generate release notes" button:
+
+
+
+Edit the pre-populated description, e.g. by summarizing multiple PRs that contributed to a single feature,
+as readers might not be and should not have to be familiar with the implementation details.
+
+By default, the new release is set as the latest release.
+Usually this is the case, but uncheck this e.g. when releasing a bugfix release for an older version.
+
+Finally, click "Publish release", and you are all done! 🎉
diff --git a/encoding/json/decode.go b/encoding/json/decode.go
index f6288deeb4..6ea90c3933 100644
--- a/encoding/json/decode.go
+++ b/encoding/json/decode.go
@@ -216,6 +216,8 @@ func (d *Decoder) decodeJSON(v any) cadence.Value {
return d.decodeEvent(valueJSON)
case contractTypeStr:
return d.decodeContract(valueJSON)
+ case linkTypeStr:
+ return d.decodeLink(valueJSON)
case pathTypeStr:
return d.decodePath(valueJSON)
case typeTypeStr:
@@ -822,6 +824,29 @@ func (d *Decoder) decodeEnum(valueJSON any) cadence.Enum {
))
}
+func (d *Decoder) decodeLink(valueJSON any) cadence.PathLink {
+ obj := toObject(valueJSON)
+
+ targetPath, ok := d.decodeJSON(obj.Get(targetPathKey)).(cadence.Path)
+ if !ok {
+ panic(errors.NewDefaultUserError("invalid link: missing or invalid target path"))
+ }
+
+ borrowType := obj.GetString(borrowTypeKey)
+
+ common.UseMemory(d.gauge, common.MemoryUsage{
+ Kind: common.MemoryKindRawString,
+ // no need to add 1 to account for empty string: string is metered in Link struct
+ Amount: uint64(len(borrowType)),
+ })
+
+ return cadence.NewMeteredLink(
+ d.gauge,
+ targetPath,
+ borrowType,
+ )
+}
+
func (d *Decoder) decodePath(valueJSON any) cadence.Path {
obj := toObject(valueJSON)
diff --git a/encoding/json/encode.go b/encoding/json/encode.go
index 7c72b49819..e58c51478e 100644
--- a/encoding/json/encode.go
+++ b/encoding/json/encode.go
@@ -126,6 +126,11 @@ type jsonCompositeField struct {
Name string `json:"name"`
}
+type jsonPathLinkValue struct {
+ TargetPath jsonValue `json:"targetPath"`
+ BorrowType string `json:"borrowType"`
+}
+
type jsonPathValue struct {
Domain string `json:"domain"`
Identifier string `json:"identifier"`
@@ -239,6 +244,7 @@ const (
resourceTypeStr = "Resource"
eventTypeStr = "Event"
contractTypeStr = "Contract"
+ linkTypeStr = "Link"
pathTypeStr = "Path"
typeTypeStr = "Type"
capabilityTypeStr = "Capability"
@@ -314,6 +320,8 @@ func Prepare(v cadence.Value) jsonValue {
return prepareEvent(x)
case cadence.Contract:
return prepareContract(x)
+ case cadence.PathLink:
+ return prepareLink(x)
case cadence.Path:
return preparePath(x)
case cadence.TypeValue:
@@ -593,6 +601,16 @@ func prepareComposite(kind, id string, fieldTypes []cadence.Field, fields []cade
}
}
+func prepareLink(x cadence.PathLink) jsonValue {
+ return jsonValueObject{
+ Type: linkTypeStr,
+ Value: jsonPathLinkValue{
+ TargetPath: preparePath(x.TargetPath),
+ BorrowType: x.BorrowType,
+ },
+ }
+}
+
func preparePath(x cadence.Path) jsonValue {
return jsonValueObject{
Type: pathTypeStr,
diff --git a/encoding/json/encoding_test.go b/encoding/json/encoding_test.go
index e4517493f0..f8c42b7fb5 100644
--- a/encoding/json/encoding_test.go
+++ b/encoding/json/encoding_test.go
@@ -1645,6 +1645,35 @@ func TestEncodeContract(t *testing.T) {
testAllEncodeAndDecode(t, simpleContract, resourceContract)
}
+func TestEncodeLink(t *testing.T) {
+
+ t.Parallel()
+
+ testEncodeAndDecode(
+ t,
+ cadence.NewPathLink(
+ cadence.NewPath("storage", "foo"),
+ "Bar",
+ ),
+ // language=json
+ `
+ {
+ "type": "Link",
+ "value": {
+ "targetPath": {
+ "type": "Path",
+ "value": {
+ "domain": "storage",
+ "identifier": "foo"
+ }
+ },
+ "borrowType": "Bar"
+ }
+ }
+ `,
+ )
+}
+
func TestEncodeSimpleTypes(t *testing.T) {
t.Parallel()
@@ -2999,7 +3028,7 @@ func TestDecodeInvalidType(t *testing.T) {
assert.Equal(t, "failed to decode JSON-Cadence value: invalid type ID for built-in: ``", err.Error())
})
- t.Run("undefined type", func(t *testing.T) {
+ t.Run("invalid type ID", func(t *testing.T) {
t.Parallel()
// language=json
@@ -3007,14 +3036,14 @@ func TestDecodeInvalidType(t *testing.T) {
{
"type": "Struct",
"value": {
- "id": "I.Foo",
+ "id": "I",
"fields": []
}
}
`
_, err := json.Decode(nil, []byte(encodedValue))
require.Error(t, err)
- assert.Equal(t, "failed to decode JSON-Cadence value: invalid type ID `I.Foo`: invalid identifier location type ID: missing qualified identifier", err.Error())
+ assert.Equal(t, "failed to decode JSON-Cadence value: invalid type ID `I`: invalid identifier location type ID: missing location", err.Error())
})
t.Run("unknown location prefix", func(t *testing.T) {
diff --git a/go.mod b/go.mod
index 04abf713bc..9f69b8797a 100644
--- a/go.mod
+++ b/go.mod
@@ -12,10 +12,10 @@ require (
github.com/k0kubun/pp v3.0.1+incompatible
github.com/leanovate/gopter v0.2.9
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381
- github.com/onflow/atree v0.4.0
+ github.com/onflow/atree v0.5.0
github.com/rivo/uniseg v0.2.1-0.20211004051800-57c86be7915a
github.com/schollz/progressbar/v3 v3.8.3
- github.com/stretchr/testify v1.7.3
+ github.com/stretchr/testify v1.8.1
github.com/tidwall/pretty v1.2.1
github.com/turbolent/prettier v0.0.0-20220320183459-661cc755135d
go.opentelemetry.io/otel v1.8.0
diff --git a/go.sum b/go.sum
index 8498bc011b..d07665e9f8 100644
--- a/go.sum
+++ b/go.sum
@@ -54,8 +54,8 @@ 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=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
-github.com/onflow/atree v0.4.0 h1:+TbNisavAkukAKhgQ4plWnvR9o5+SkwPIsi3jaeAqKs=
-github.com/onflow/atree v0.4.0/go.mod h1:7Qe1xaW0YewvouLXrugzMFUYXNoRQ8MT/UsVAWx1Ndo=
+github.com/onflow/atree v0.5.0 h1:y3lh8hY2fUo8KVE2ALVcz0EiNTq0tXJ6YTXKYVDA+3E=
+github.com/onflow/atree v0.5.0/go.mod h1:gBHU0M05qCbv9NN0kijLWMgC47gHVNBIp4KmsVFi0tc=
github.com/pkg/term v1.1.0 h1:xIAAdCMh3QIAy+5FrE8Ad8XoDhEU4ufwbaSozViP9kk=
github.com/pkg/term v1.1.0/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -67,13 +67,15 @@ github.com/schollz/progressbar/v3 v3.8.3 h1:FnLGl3ewlDUP+YdSwveXBaXs053Mem/du+wr
github.com/schollz/progressbar/v3 v3.8.3/go.mod h1:pWnVCjSBZsT2X3nx9HfRdnCDrpbevliMeoEVhStwHko=
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.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.3 h1:dAm0YRdRQlWojc3CrCRgPBzG5f941d0zvAKu7qY4e+I=
-github.com/stretchr/testify v1.7.3/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/texttheater/golang-levenshtein/levenshtein v0.0.0-20200805054039-cae8b0eaed6c h1:HelZ2kAFadG0La9d+4htN4HzQ68Bm2iM9qKMSMES6xg=
github.com/texttheater/golang-levenshtein/levenshtein v0.0.0-20200805054039-cae8b0eaed6c/go.mod h1:JlzghshsemAMDGZLytTFY8C1JQxQPhnatWqNwUXjggo=
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
diff --git a/npm-packages/cadence-parser/package.json b/npm-packages/cadence-parser/package.json
index 40b5906fbc..970092b0f6 100644
--- a/npm-packages/cadence-parser/package.json
+++ b/npm-packages/cadence-parser/package.json
@@ -1,6 +1,6 @@
{
"name": "@onflow/cadence-parser",
- "version": "0.35.0",
+ "version": "0.37.0",
"description": "The Cadence parser",
"homepage": "https://github.com/onflow/cadence",
"repository": {
diff --git a/runtime/account_test.go b/runtime/account_test.go
index cd27af20ee..3adf6d918e 100644
--- a/runtime/account_test.go
+++ b/runtime/account_test.go
@@ -1466,7 +1466,7 @@ func TestRuntimePublicKey(t *testing.T) {
publicKey: "0102".decodeHex(),
signatureAlgorithm: SignatureAlgorithm.ECDSA_P256
)
-
+
var publickeyRef = &publicKey.publicKey as &[UInt8]
publickeyRef[0] = 3
@@ -1524,7 +1524,7 @@ func TestAuthAccountContracts(t *testing.T) {
getSigningAccounts: func() ([]Address, error) {
return []Address{{42}}, nil
},
- getAccountContractCode: func(address Address, name string) ([]byte, error) {
+ getAccountContractCode: func(_ common.AddressLocation) ([]byte, error) {
invoked = true
return []byte{1, 2}, nil
},
@@ -1566,7 +1566,7 @@ func TestAuthAccountContracts(t *testing.T) {
getSigningAccounts: func() ([]Address, error) {
return []Address{{42}}, nil
},
- getAccountContractCode: func(address Address, name string) ([]byte, error) {
+ getAccountContractCode: func(_ common.AddressLocation) ([]byte, error) {
invoked = true
return nil, nil
},
@@ -1605,18 +1605,10 @@ func TestAuthAccountContracts(t *testing.T) {
return []Address{{0, 0, 0, 0, 0, 0, 0, 0x42}}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
@@ -1628,7 +1620,7 @@ func TestAuthAccountContracts(t *testing.T) {
nextTransactionLocation := newTransactionLocationGenerator()
- // Deploy contract interface
+ // Deploy contract interface
err := rt.ExecuteTransaction(
Script{
Source: DeploymentTransaction("HelloInterface", []byte(`
@@ -1706,18 +1698,10 @@ func TestAuthAccountContracts(t *testing.T) {
return []Address{{0, 0, 0, 0, 0, 0, 0, 0x42}}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
@@ -1729,7 +1713,7 @@ func TestAuthAccountContracts(t *testing.T) {
nextTransactionLocation := newTransactionLocationGenerator()
- // Deploy contract interface
+ // Deploy contract interface
err := rt.ExecuteTransaction(
Script{
Source: DeploymentTransaction("HelloInterface", []byte(`
@@ -1798,7 +1782,7 @@ func TestAuthAccountContracts(t *testing.T) {
getSigningAccounts: func() ([]Address, error) {
return []Address{{0, 0, 0, 0, 0, 0, 0, 0x42}}, nil
},
- getAccountContractCode: func(address Address, name string) ([]byte, error) {
+ getAccountContractCode: func(_ common.AddressLocation) ([]byte, error) {
return nil, nil
},
}
@@ -1970,7 +1954,7 @@ func TestPublicAccountContracts(t *testing.T) {
getSigningAccounts: func() ([]Address, error) {
return []Address{{42}}, nil
},
- getAccountContractCode: func(address Address, name string) ([]byte, error) {
+ getAccountContractCode: func(_ common.AddressLocation) ([]byte, error) {
invoked = true
return []byte{1, 2}, nil
},
@@ -2026,7 +2010,7 @@ func TestPublicAccountContracts(t *testing.T) {
getSigningAccounts: func() ([]Address, error) {
return []Address{{42}}, nil
},
- getAccountContractCode: func(address Address, name string) ([]byte, error) {
+ getAccountContractCode: func(_ common.AddressLocation) ([]byte, error) {
invoked = true
return nil, nil
},
@@ -2354,18 +2338,10 @@ func TestRuntimeAccountLink(t *testing.T) {
return []Address{signerAccount}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) (err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) (err error) {
accountCodes[location] = code
return nil
},
@@ -2425,18 +2401,11 @@ func TestRuntimeAccountLink(t *testing.T) {
return []Address{signerAccount}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
+
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) (err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) (err error) {
accountCodes[location] = code
return nil
},
@@ -2452,7 +2421,7 @@ func TestRuntimeAccountLink(t *testing.T) {
setupTransaction := []byte(`
transaction {
prepare(acct: AuthAccount) {
- acct.linkAccount(/public/foo)
+ acct.linkAccount(/private/foo)
}
}
`)
@@ -2468,10 +2437,11 @@ func TestRuntimeAccountLink(t *testing.T) {
)
require.Error(t, err)
- assert.ErrorContains(t, err, "value of type `AuthAccount` has no member `linkAccount`")
+ var accountLinkingForbiddenErr interpreter.AccountLinkingForbiddenError
+ assert.ErrorAs(t, err, &accountLinkingForbiddenErr)
})
- t.Run("enabled, pragma", func(t *testing.T) {
+ t.Run("publish and claim", func(t *testing.T) {
t.Parallel()
@@ -2485,6 +2455,7 @@ func TestRuntimeAccountLink(t *testing.T) {
accountCodes := map[Location][]byte{}
var logs []string
+ var events []cadence.Event
signerAccount := address1
@@ -2497,24 +2468,20 @@ func TestRuntimeAccountLink(t *testing.T) {
return []Address{signerAccount}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) (err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) (err error) {
accountCodes[location] = code
return nil
},
log: func(message string) {
logs = append(logs, message)
},
+ emitEvent: func(event cadence.Event) error {
+ events = append(events, event)
+ return nil
+ },
}
nextTransactionLocation := newTransactionLocationGenerator()
@@ -2526,7 +2493,8 @@ func TestRuntimeAccountLink(t *testing.T) {
transaction {
prepare(acct: AuthAccount) {
- acct.linkAccount(/public/foo)
+ let cap = acct.linkAccount(/private/foo)!
+ log(acct.inbox.publish(cap, name: "foo", recipient: 0x2))
}
}
`)
@@ -2544,14 +2512,32 @@ func TestRuntimeAccountLink(t *testing.T) {
)
require.NoError(t, err)
- // Access
+ require.Len(t, events, 2)
+
+ require.Equal(t,
+ string(stdlib.AccountLinkedEventType.ID()),
+ events[0].EventType.ID(),
+ )
+ require.Equal(t,
+ []cadence.Value{
+ cadence.NewAddress(common.MustBytesToAddress([]byte{0x1})),
+ cadence.NewPath("private", "foo"),
+ },
+ events[0].Fields,
+ )
+
+ require.Equal(t,
+ string(stdlib.AccountInboxPublishedEventType.ID()),
+ events[1].EventType.ID(),
+ )
+
+ // Claim
accessTransaction := []byte(`
transaction {
prepare(acct: AuthAccount) {
- let ref = getAccount(0x1)
- .getCapability<&AuthAccount>(/public/foo)
- .borrow()!
+ let cap = acct.inbox.claim<&AuthAccount>("foo", provider: 0x1)!
+ let ref = cap.borrow()!
log(ref.address)
}
}
@@ -2571,12 +2557,12 @@ func TestRuntimeAccountLink(t *testing.T) {
require.NoError(t, err)
require.Equal(t,
- []string{"0x0000000000000001"},
+ []string{"()", "0x0000000000000001"},
logs,
)
})
- t.Run("publish and claim", func(t *testing.T) {
+ t.Run("enabled, contract, missing pragma", func(t *testing.T) {
t.Parallel()
@@ -2585,14 +2571,13 @@ func TestRuntimeAccountLink(t *testing.T) {
AccountLinkingEnabled: true,
})
- address1 := common.MustBytesToAddress([]byte{0x1})
- address2 := common.MustBytesToAddress([]byte{0x2})
+ address := common.MustBytesToAddress([]byte{0x1})
accountCodes := map[Location][]byte{}
var logs []string
var events []cadence.Event
- signerAccount := address1
+ signerAccount := address
runtimeInterface := &testRuntimeInterface{
getCode: func(location Location) (bytes []byte, err error) {
@@ -2603,18 +2588,10 @@ func TestRuntimeAccountLink(t *testing.T) {
return []Address{signerAccount}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) (err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) (err error) {
accountCodes[location] = code
return nil
},
@@ -2629,24 +2606,118 @@ func TestRuntimeAccountLink(t *testing.T) {
nextTransactionLocation := newTransactionLocationGenerator()
+ // Deploy contract
+ err := runtime.ExecuteTransaction(
+ Script{
+ Source: DeploymentTransaction(
+ "AccountLinker",
+ []byte(`
+ // should have no influence
+ #allowAccountLinking
+
+ pub contract AccountLinker {
+
+ pub fun link(_ account: AuthAccount) {
+ account.linkAccount(/private/foo)
+ }
+ }
+ `,
+ ),
+ ),
+ },
+ Context{
+ Interface: runtimeInterface,
+ Location: nextTransactionLocation(),
+ },
+ )
+ require.NoError(t, err)
+
// Set up account
setupTransaction := []byte(`
- #allowAccountLinking
+ import AccountLinker from 0x1
transaction {
- prepare(acct: AuthAccount) {
- let cap = acct.linkAccount(/private/foo)!
- log(acct.inbox.publish(cap, name: "foo", recipient: 0x2))
+ prepare(signer: AuthAccount) {
+ AccountLinker.link(signer)
}
}
`)
- signerAccount = address1
+ err = runtime.ExecuteTransaction(
+ Script{
+ Source: setupTransaction,
+ },
+ Context{
+ Interface: runtimeInterface,
+ Location: nextTransactionLocation(),
+ },
+ )
+ require.Error(t, err)
+
+ var accountLinkingForbiddenErr interpreter.AccountLinkingForbiddenError
+ assert.ErrorAs(t, err, &accountLinkingForbiddenErr)
+ })
+
+ t.Run("enabled, contract, pragma in tx", func(t *testing.T) {
+
+ t.Parallel()
+
+ runtime := NewInterpreterRuntime(Config{
+ AtreeValidationEnabled: true,
+ AccountLinkingEnabled: true,
+ })
+
+ address := common.MustBytesToAddress([]byte{0x1})
+
+ accountCodes := map[Location][]byte{}
+ var logs []string
+ var events []cadence.Event
+
+ signerAccount := address
+
+ runtimeInterface := &testRuntimeInterface{
+ getCode: func(location Location) (bytes []byte, err error) {
+ return accountCodes[location], nil
+ },
+ storage: newTestLedger(nil, nil),
+ getSigningAccounts: func() ([]Address, error) {
+ return []Address{signerAccount}, nil
+ },
+ resolveLocation: singleIdentifierLocationResolver(t),
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
+ return accountCodes[location], nil
+ },
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) (err error) {
+ accountCodes[location] = code
+ return nil
+ },
+ log: func(message string) {
+ logs = append(logs, message)
+ },
+ emitEvent: func(event cadence.Event) error {
+ events = append(events, event)
+ return nil
+ },
+ }
+
+ nextTransactionLocation := newTransactionLocationGenerator()
+ // Deploy contract
err := runtime.ExecuteTransaction(
Script{
- Source: setupTransaction,
+ Source: DeploymentTransaction(
+ "AccountLinker",
+ []byte(`
+ pub contract AccountLinker {
+
+ pub fun link(_ account: AuthAccount) {
+ account.linkAccount(/private/foo)
+ }
+ }
+ `,
+ ),
+ ),
},
Context{
Interface: runtimeInterface,
@@ -2655,23 +2726,25 @@ func TestRuntimeAccountLink(t *testing.T) {
)
require.NoError(t, err)
- // Claim
+ // Set up account
+
+ setupTransaction := []byte(`
+ #allowAccountLinking
+
+ import AccountLinker from 0x1
- accessTransaction := []byte(`
transaction {
- prepare(acct: AuthAccount) {
- let cap = acct.inbox.claim<&AuthAccount>("foo", provider: 0x1)!
- let ref = cap.borrow()!
- log(ref.address)
+ prepare(signer: AuthAccount) {
+ AccountLinker.link(signer)
}
}
`)
- signerAccount = address2
+ events = nil
err = runtime.ExecuteTransaction(
Script{
- Source: accessTransaction,
+ Source: setupTransaction,
},
Context{
Interface: runtimeInterface,
@@ -2680,9 +2753,126 @@ func TestRuntimeAccountLink(t *testing.T) {
)
require.NoError(t, err)
+ require.Len(t, events, 1)
+
require.Equal(t,
- []string{"()", "0x0000000000000001"},
- logs,
+ string(stdlib.AccountLinkedEventType.ID()),
+ events[0].EventType.ID(),
+ )
+ require.Equal(t,
+ []cadence.Value{
+ cadence.NewAddress(common.MustBytesToAddress([]byte{0x1})),
+ cadence.NewPath("private", "foo"),
+ },
+ events[0].Fields,
)
})
+
+ t.Run("enabled, contract, pragma in script", func(t *testing.T) {
+
+ t.Parallel()
+
+ runtime := NewInterpreterRuntime(Config{
+ AtreeValidationEnabled: true,
+ AccountLinkingEnabled: true,
+ })
+
+ address := common.MustBytesToAddress([]byte{0x1})
+
+ accountCodes := map[Location][]byte{}
+ var logs []string
+ var events []cadence.Event
+
+ signerAccount := address
+
+ runtimeInterface := &testRuntimeInterface{
+ getCode: func(location Location) (bytes []byte, err error) {
+ return accountCodes[location], nil
+ },
+ storage: newTestLedger(nil, nil),
+ getSigningAccounts: func() ([]Address, error) {
+ return []Address{signerAccount}, nil
+ },
+ resolveLocation: singleIdentifierLocationResolver(t),
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
+ return accountCodes[location], nil
+ },
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) (err error) {
+ accountCodes[location] = code
+ return nil
+ },
+ log: func(message string) {
+ logs = append(logs, message)
+ },
+ emitEvent: func(event cadence.Event) error {
+ events = append(events, event)
+ return nil
+ },
+ }
+
+ nextTransactionLocation := newTransactionLocationGenerator()
+
+ // Deploy contract
+ err := runtime.ExecuteTransaction(
+ Script{
+ Source: DeploymentTransaction(
+ "AccountLinker",
+ []byte(`
+ pub contract AccountLinker {
+
+ pub fun link(_ account: AuthAccount) {
+ account.linkAccount(/private/foo)
+ }
+ }
+ `,
+ ),
+ ),
+ },
+ Context{
+ Interface: runtimeInterface,
+ Location: nextTransactionLocation(),
+ },
+ )
+ require.NoError(t, err)
+
+ // Set up account
+
+ setupTransaction := []byte(`
+ #allowAccountLinking
+
+ import AccountLinker from 0x1
+
+ pub fun main() {
+ AccountLinker.link(getAuthAccount(0x1))
+ }
+ `)
+
+ events = nil
+
+ _, err = runtime.ExecuteScript(
+ Script{
+ Source: setupTransaction,
+ },
+ Context{
+ Interface: runtimeInterface,
+ Location: common.ScriptLocation{},
+ },
+ )
+ require.NoError(t, err)
+
+ require.Len(t, events, 1)
+
+ require.Equal(t,
+ string(stdlib.AccountLinkedEventType.ID()),
+ events[0].EventType.ID(),
+ )
+ require.Equal(t,
+ []cadence.Value{
+ cadence.NewAddress(common.MustBytesToAddress([]byte{0x1})),
+ cadence.NewPath("private", "foo"),
+ },
+ events[0].Fields,
+ )
+ })
+
}
diff --git a/runtime/attachments_test.go b/runtime/attachments_test.go
index 6ded7869b1..8a5cadfaac 100644
--- a/runtime/attachments_test.go
+++ b/runtime/attachments_test.go
@@ -98,19 +98,11 @@ func TestAccountAttachmentSaveAndLoad(t *testing.T) {
getSigningAccounts: func() ([]Address, error) {
return []Address{[8]byte{0, 0, 0, 0, 0, 0, 0, 1}}, nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
code = accountCodes[location]
return code, nil
},
@@ -197,19 +189,11 @@ func TestAccountAttachmentExportFailure(t *testing.T) {
getSigningAccounts: func() ([]Address, error) {
return []Address{[8]byte{0, 0, 0, 0, 0, 0, 0, 1}}, nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
code = accountCodes[location]
return code, nil
},
@@ -287,19 +271,11 @@ func TestAccountAttachmentExport(t *testing.T) {
getSigningAccounts: func() ([]Address, error) {
return []Address{[8]byte{0, 0, 0, 0, 0, 0, 0, 1}}, nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
code = accountCodes[location]
return code, nil
},
@@ -374,19 +350,11 @@ func TestAccountAttachedExport(t *testing.T) {
getSigningAccounts: func() ([]Address, error) {
return []Address{[8]byte{0, 0, 0, 0, 0, 0, 0, 1}}, nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
code = accountCodes[location]
return code, nil
},
@@ -489,19 +457,11 @@ func TestAccountAttachmentSaveAndBorrow(t *testing.T) {
getSigningAccounts: func() ([]Address, error) {
return []Address{[8]byte{0, 0, 0, 0, 0, 0, 0, 1}}, nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
code = accountCodes[location]
return code, nil
},
@@ -613,19 +573,11 @@ func TestAccountAttachmentCapability(t *testing.T) {
getSigningAccounts: func() ([]Address, error) {
return []Address{[8]byte{0, 0, 0, 0, 0, 0, 0, 1}}, nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
code = accountCodes[location]
return code, nil
},
@@ -644,19 +596,11 @@ func TestAccountAttachmentCapability(t *testing.T) {
getSigningAccounts: func() ([]Address, error) {
return []Address{[8]byte{0, 0, 0, 0, 0, 0, 0, 2}}, nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
code = accountCodes[location]
return code, nil
},
diff --git a/runtime/common/addresslocation.go b/runtime/common/addresslocation.go
index 5b13c16f7e..f283f87078 100644
--- a/runtime/common/addresslocation.go
+++ b/runtime/common/addresslocation.go
@@ -85,6 +85,10 @@ func (l AddressLocation) Description() string {
)
}
+func (l AddressLocation) ID() string {
+ return fmt.Sprintf("%s.%s", AddressLocationPrefix, l)
+}
+
func (l AddressLocation) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
Type string
@@ -140,9 +144,7 @@ func decodeAddressLocationTypeID(gauge MemoryGauge, typeID string) (AddressLocat
panic(errors.NewUnreachableError())
case 1:
return newError("missing location")
- case 2:
- return newError("missing qualified identifier")
- case 3, 4:
+ case 2, 3, 4:
break
default:
// strings.SplitN will never return more than 4 parts
@@ -177,6 +179,11 @@ func decodeAddressLocationTypeID(gauge MemoryGauge, typeID string) (AddressLocat
var qualifiedIdentifier string
switch partCount {
+ case 2:
+ // If there are only 2 parts,
+ // then `` is empty,
+ // and both the contract name and the qualified identifier are empty (default)s
+
case 3:
// If there are only 3 parts,
// then `` is both the contract name and the qualified identifier.
diff --git a/runtime/common/addresslocation_test.go b/runtime/common/addresslocation_test.go
index 9337e15ed0..fdea7c4087 100644
--- a/runtime/common/addresslocation_test.go
+++ b/runtime/common/addresslocation_test.go
@@ -65,6 +65,19 @@ func TestAddressLocationTypeID(t *testing.T) {
)
}
+func TestAddressLocationID(t *testing.T) {
+
+ t.Parallel()
+
+ location, _, err := decodeAddressLocationTypeID(nil, "A.0000000000000001.Bar.Baz")
+ require.NoError(t, err)
+
+ assert.Equal(t,
+ "A.0000000000000001.Bar",
+ location.ID(),
+ )
+}
+
func TestDecodeAddressLocationTypeID(t *testing.T) {
t.Parallel()
@@ -85,12 +98,38 @@ func TestDecodeAddressLocationTypeID(t *testing.T) {
require.EqualError(t, err, "invalid address location type ID: missing location")
})
- t.Run("missing qualified identifier", func(t *testing.T) {
+ t.Run("missing qualified identifier part", func(t *testing.T) {
+
+ t.Parallel()
+
+ location, qualifiedIdentifier, err := decodeAddressLocationTypeID(nil, "A.0000000000000001")
+ require.NoError(t, err)
+
+ assert.Equal(t,
+ AddressLocation{
+ Address: MustBytesToAddress([]byte{1}),
+ Name: "",
+ },
+ location,
+ )
+ assert.Equal(t, "", qualifiedIdentifier)
+ })
+
+ t.Run("empty qualified identifier", func(t *testing.T) {
t.Parallel()
- _, _, err := decodeAddressLocationTypeID(nil, "A.0000000000000001")
- require.EqualError(t, err, "invalid address location type ID: missing qualified identifier")
+ location, qualifiedIdentifier, err := decodeAddressLocationTypeID(nil, "A.0000000000000001.")
+ require.NoError(t, err)
+
+ assert.Equal(t,
+ AddressLocation{
+ Address: MustBytesToAddress([]byte{1}),
+ Name: "",
+ },
+ location,
+ )
+ assert.Equal(t, "", qualifiedIdentifier)
})
t.Run("invalid prefix", func(t *testing.T) {
diff --git a/runtime/common/computationkind.go b/runtime/common/computationkind.go
index cf02d9f80a..90b96e858e 100644
--- a/runtime/common/computationkind.go
+++ b/runtime/common/computationkind.go
@@ -109,7 +109,7 @@ const (
_
_
_
- _
+ ComputationKindEncodeValue
_
_
_
diff --git a/runtime/common/computationkind_string.go b/runtime/common/computationkind_string.go
index 37dfb948d2..9ed621d72f 100644
--- a/runtime/common/computationkind_string.go
+++ b/runtime/common/computationkind_string.go
@@ -21,6 +21,7 @@ func _() {
_ = x[ComputationKindCreateDictionaryValue-1040]
_ = x[ComputationKindTransferDictionaryValue-1041]
_ = x[ComputationKindDestroyDictionaryValue-1042]
+ _ = x[ComputationKindEncodeValue-1080]
_ = x[ComputationKindSTDLIBPanic-1100]
_ = x[ComputationKindSTDLIBAssert-1101]
_ = x[ComputationKindSTDLIBUnsafeRandom-1102]
@@ -34,8 +35,9 @@ const (
_ComputationKind_name_2 = "CreateCompositeValueTransferCompositeValueDestroyCompositeValue"
_ComputationKind_name_3 = "CreateArrayValueTransferArrayValueDestroyArrayValue"
_ComputationKind_name_4 = "CreateDictionaryValueTransferDictionaryValueDestroyDictionaryValue"
- _ComputationKind_name_5 = "STDLIBPanicSTDLIBAssertSTDLIBUnsafeRandom"
- _ComputationKind_name_6 = "STDLIBRLPDecodeStringSTDLIBRLPDecodeList"
+ _ComputationKind_name_5 = "EncodeValue"
+ _ComputationKind_name_6 = "STDLIBPanicSTDLIBAssertSTDLIBUnsafeRandom"
+ _ComputationKind_name_7 = "STDLIBRLPDecodeStringSTDLIBRLPDecodeList"
)
var (
@@ -43,8 +45,8 @@ var (
_ComputationKind_index_2 = [...]uint8{0, 20, 42, 63}
_ComputationKind_index_3 = [...]uint8{0, 16, 34, 51}
_ComputationKind_index_4 = [...]uint8{0, 21, 44, 66}
- _ComputationKind_index_5 = [...]uint8{0, 11, 23, 41}
- _ComputationKind_index_6 = [...]uint8{0, 21, 40}
+ _ComputationKind_index_6 = [...]uint8{0, 11, 23, 41}
+ _ComputationKind_index_7 = [...]uint8{0, 21, 40}
)
func (i ComputationKind) String() string {
@@ -63,12 +65,14 @@ func (i ComputationKind) String() string {
case 1040 <= i && i <= 1042:
i -= 1040
return _ComputationKind_name_4[_ComputationKind_index_4[i]:_ComputationKind_index_4[i+1]]
+ case i == 1080:
+ return _ComputationKind_name_5
case 1100 <= i && i <= 1102:
i -= 1100
- return _ComputationKind_name_5[_ComputationKind_index_5[i]:_ComputationKind_index_5[i+1]]
+ return _ComputationKind_name_6[_ComputationKind_index_6[i]:_ComputationKind_index_6[i+1]]
case 1108 <= i && i <= 1109:
i -= 1108
- return _ComputationKind_name_6[_ComputationKind_index_6[i]:_ComputationKind_index_6[i+1]]
+ return _ComputationKind_name_7[_ComputationKind_index_7[i]:_ComputationKind_index_7[i+1]]
default:
return "ComputationKind(" + strconv.FormatInt(int64(i), 10) + ")"
}
diff --git a/runtime/common/identifierlocation.go b/runtime/common/identifierlocation.go
index d17ef49398..ce07bdf579 100644
--- a/runtime/common/identifierlocation.go
+++ b/runtime/common/identifierlocation.go
@@ -20,6 +20,7 @@ package common
import (
"encoding/json"
+ "fmt"
"strings"
"github.com/onflow/cadence/runtime/errors"
@@ -64,6 +65,10 @@ func (l IdentifierLocation) Description() string {
return string(l)
}
+func (l IdentifierLocation) ID() string {
+ return fmt.Sprintf("%s.%s", IdentifierLocationPrefix, l)
+}
+
func (l IdentifierLocation) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
Type string
@@ -98,11 +103,8 @@ func decodeIdentifierLocationTypeID(_ MemoryGauge, typeID string) (IdentifierLoc
parts := strings.SplitN(typeID, ".", 3)
pieceCount := len(parts)
- switch pieceCount {
- case 1:
+ if pieceCount == 1 {
return newError("missing location")
- case 2:
- return newError("missing qualified identifier")
}
prefix := parts[0]
@@ -117,7 +119,11 @@ func decodeIdentifierLocationTypeID(_ MemoryGauge, typeID string) (IdentifierLoc
}
location := IdentifierLocation(parts[1])
- qualifiedIdentifier := parts[2]
+
+ var qualifiedIdentifier string
+ if pieceCount > 2 {
+ qualifiedIdentifier = parts[2]
+ }
return location, qualifiedIdentifier, nil
}
diff --git a/runtime/common/identifierlocation_test.go b/runtime/common/identifierlocation_test.go
index 6e19e09971..35a5d833cb 100644
--- a/runtime/common/identifierlocation_test.go
+++ b/runtime/common/identifierlocation_test.go
@@ -58,6 +58,19 @@ func TestIdentifierLocation_TypeID(t *testing.T) {
)
}
+func TestIdentifierLocation_ID(t *testing.T) {
+
+ t.Parallel()
+
+ location, _, err := decodeIdentifierLocationTypeID(nil, "I.foo.Bar.Baz")
+ require.NoError(t, err)
+
+ assert.Equal(t,
+ "I.foo",
+ location.ID(),
+ )
+}
+
func TestDecodeIdentifierLocationTypeID(t *testing.T) {
t.Parallel()
@@ -78,15 +91,35 @@ func TestDecodeIdentifierLocationTypeID(t *testing.T) {
require.EqualError(t, err, "invalid identifier location type ID: missing location")
})
- t.Run("missing qualified identifier", func(t *testing.T) {
+ t.Run("missing qualified identifier part", func(t *testing.T) {
+
+ t.Parallel()
+
+ location, qualifiedIdentifier, err := decodeIdentifierLocationTypeID(nil, "I.test")
+ require.NoError(t, err)
+
+ assert.Equal(t,
+ IdentifierLocation("test"),
+ location,
+ )
+ assert.Equal(t, "", qualifiedIdentifier)
+ })
+
+ t.Run("empty qualified identifier", func(t *testing.T) {
t.Parallel()
- _, _, err := decodeIdentifierLocationTypeID(nil, "I.test")
- require.EqualError(t, err, "invalid identifier location type ID: missing qualified identifier")
+ location, qualifiedIdentifier, err := decodeIdentifierLocationTypeID(nil, "I.test.")
+ require.NoError(t, err)
+
+ assert.Equal(t,
+ IdentifierLocation("test"),
+ location,
+ )
+ assert.Equal(t, "", qualifiedIdentifier)
})
- t.Run("missing qualified identifier", func(t *testing.T) {
+ t.Run("invalid prefix", func(t *testing.T) {
t.Parallel()
diff --git a/runtime/common/location.go b/runtime/common/location.go
index c3c815b688..bb22061874 100644
--- a/runtime/common/location.go
+++ b/runtime/common/location.go
@@ -36,6 +36,9 @@ type Location interface {
QualifiedIdentifier(typeID TypeID) string
// Description returns a human-readable description. For example, it can be used in error messages
Description() string
+ // ID returns a string representation of the location, including the location prefix.
+ // This is helpful to differentiate a location, e.g in the context of code coverage.
+ ID() string
}
// LocationsInSameAccount returns true if both locations are nil,
diff --git a/runtime/common/repllocation.go b/runtime/common/repllocation.go
index 632c737d7d..fd626bc28a 100644
--- a/runtime/common/repllocation.go
+++ b/runtime/common/repllocation.go
@@ -71,6 +71,10 @@ func (l REPLLocation) Description() string {
return REPLLocationPrefix
}
+func (l REPLLocation) ID() string {
+ return REPLLocationPrefix
+}
+
func (l REPLLocation) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
Type string
@@ -102,11 +106,6 @@ func decodeREPLLocationTypeID(typeID string) (REPLLocation, string, error) {
parts := strings.SplitN(typeID, ".", 2)
- pieceCount := len(parts)
- if pieceCount == 1 {
- return newError("missing qualified identifier")
- }
-
prefix := parts[0]
if prefix != REPLLocationPrefix {
@@ -118,7 +117,11 @@ func decodeREPLLocationTypeID(typeID string) (REPLLocation, string, error) {
)
}
- qualifiedIdentifier := parts[1]
+ pieceCount := len(parts)
+ var qualifiedIdentifier string
+ if pieceCount > 1 {
+ qualifiedIdentifier = parts[1]
+ }
return REPLLocation{}, qualifiedIdentifier, nil
}
diff --git a/runtime/common/repllocation_test.go b/runtime/common/repllocation_test.go
index 7c6d9718f5..a153610ee1 100644
--- a/runtime/common/repllocation_test.go
+++ b/runtime/common/repllocation_test.go
@@ -57,6 +57,19 @@ func TestREPLLocation_TypeID(t *testing.T) {
)
}
+func TestREPLLocation_ID(t *testing.T) {
+
+ t.Parallel()
+
+ location, _, err := decodeREPLLocationTypeID("REPL.Bar.Baz")
+ require.NoError(t, err)
+
+ assert.Equal(t,
+ "REPL",
+ location.ID(),
+ )
+}
+
func TestDecodeREPLLocationTypeID(t *testing.T) {
t.Parallel()
@@ -69,15 +82,35 @@ func TestDecodeREPLLocationTypeID(t *testing.T) {
require.EqualError(t, err, "invalid REPL location type ID: missing prefix")
})
- t.Run("missing qualified identifier", func(t *testing.T) {
+ t.Run("missing qualified identifier part", func(t *testing.T) {
+
+ t.Parallel()
+
+ location, qualifiedIdentifier, err := decodeREPLLocationTypeID("REPL")
+ require.NoError(t, err)
+
+ assert.Equal(t,
+ REPLLocation{},
+ location,
+ )
+ assert.Equal(t, "", qualifiedIdentifier)
+ })
+
+ t.Run("empty qualified identifier", func(t *testing.T) {
t.Parallel()
- _, _, err := decodeREPLLocationTypeID("REPL")
- require.EqualError(t, err, "invalid REPL location type ID: missing qualified identifier")
+ location, qualifiedIdentifier, err := decodeREPLLocationTypeID("REPL.")
+ require.NoError(t, err)
+
+ assert.Equal(t,
+ REPLLocation{},
+ location,
+ )
+ assert.Equal(t, "", qualifiedIdentifier)
})
- t.Run("missing qualified identifier", func(t *testing.T) {
+ t.Run("invalid prefix", func(t *testing.T) {
t.Parallel()
diff --git a/runtime/common/scriptlocation.go b/runtime/common/scriptlocation.go
index ef1f911c06..2942d9d101 100644
--- a/runtime/common/scriptlocation.go
+++ b/runtime/common/scriptlocation.go
@@ -70,6 +70,10 @@ func (l ScriptLocation) Description() string {
return fmt.Sprintf("script with ID %s", hex.EncodeToString(l[:]))
}
+func (l ScriptLocation) ID() string {
+ return fmt.Sprintf("%s.%s", ScriptLocationPrefix, l)
+}
+
func (l ScriptLocation) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
Type string
diff --git a/runtime/common/scriptlocation_test.go b/runtime/common/scriptlocation_test.go
index 365ae28846..82a4f21d30 100644
--- a/runtime/common/scriptlocation_test.go
+++ b/runtime/common/scriptlocation_test.go
@@ -58,6 +58,22 @@ func TestScriptLocationTypeID(t *testing.T) {
)
}
+func TestScriptLocationID(t *testing.T) {
+
+ t.Parallel()
+
+ location, _, err := decodeScriptLocationTypeID(
+ nil,
+ "s.0102000000000000000000000000000000000000000000000000000000000000.Bar.Baz",
+ )
+ require.NoError(t, err)
+
+ assert.Equal(t,
+ "s.0102000000000000000000000000000000000000000000000000000000000000",
+ location.ID(),
+ )
+}
+
func TestDecodeScriptLocationTypeID(t *testing.T) {
t.Parallel()
@@ -89,10 +105,10 @@ func TestDecodeScriptLocationTypeID(t *testing.T) {
ScriptLocation{0x1, 0x2},
location,
)
- assert.Empty(t, qualifiedIdentifier)
+ assert.Equal(t, "", qualifiedIdentifier)
})
- t.Run("missing qualified identifier", func(t *testing.T) {
+ t.Run("invalid prefix", func(t *testing.T) {
t.Parallel()
diff --git a/runtime/common/stringlocation.go b/runtime/common/stringlocation.go
index 124cfc3d44..17532f665e 100644
--- a/runtime/common/stringlocation.go
+++ b/runtime/common/stringlocation.go
@@ -20,6 +20,7 @@ package common
import (
"encoding/json"
+ "fmt"
"strings"
"github.com/onflow/cadence/runtime/errors"
@@ -64,6 +65,10 @@ func (l StringLocation) Description() string {
return string(l)
}
+func (l StringLocation) ID() string {
+ return fmt.Sprintf("%s.%s", StringLocationPrefix, l)
+}
+
func (l StringLocation) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
Type string
@@ -98,11 +103,8 @@ func decodeStringLocationTypeID(gauge MemoryGauge, typeID string) (StringLocatio
parts := strings.SplitN(typeID, ".", 3)
pieceCount := len(parts)
- switch pieceCount {
- case 1:
+ if pieceCount == 1 {
return newError("missing location")
- case 2:
- return newError("missing qualified identifier")
}
prefix := parts[0]
@@ -117,7 +119,10 @@ func decodeStringLocationTypeID(gauge MemoryGauge, typeID string) (StringLocatio
}
location := NewStringLocation(gauge, parts[1])
- qualifiedIdentifier := parts[2]
+ var qualifiedIdentifier string
+ if pieceCount > 2 {
+ qualifiedIdentifier = parts[2]
+ }
return location, qualifiedIdentifier, nil
}
diff --git a/runtime/common/stringlocation_test.go b/runtime/common/stringlocation_test.go
index 8fc378314d..d2c9ffd93d 100644
--- a/runtime/common/stringlocation_test.go
+++ b/runtime/common/stringlocation_test.go
@@ -58,6 +58,19 @@ func TestStringLocation_TypeID(t *testing.T) {
)
}
+func TestStringLocation_ID(t *testing.T) {
+
+ t.Parallel()
+
+ location, _, err := decodeStringLocationTypeID(nil, "S.foo.Bar.Baz")
+ require.NoError(t, err)
+
+ assert.Equal(t,
+ "S.foo",
+ location.ID(),
+ )
+}
+
func TestDecodeStringLocationTypeID(t *testing.T) {
t.Parallel()
@@ -78,15 +91,35 @@ func TestDecodeStringLocationTypeID(t *testing.T) {
require.EqualError(t, err, "invalid string location type ID: missing location")
})
- t.Run("missing qualified identifier", func(t *testing.T) {
+ t.Run("missing qualified identifier part", func(t *testing.T) {
+
+ t.Parallel()
+
+ location, qualifiedIdentifier, err := decodeStringLocationTypeID(nil, "S.test")
+ require.NoError(t, err)
+
+ assert.Equal(t,
+ StringLocation("test"),
+ location,
+ )
+ assert.Equal(t, "", qualifiedIdentifier)
+ })
+
+ t.Run("empty qualified identifier", func(t *testing.T) {
t.Parallel()
- _, _, err := decodeStringLocationTypeID(nil, "S.test")
- require.EqualError(t, err, "invalid string location type ID: missing qualified identifier")
+ location, qualifiedIdentifier, err := decodeStringLocationTypeID(nil, "S.test.")
+ require.NoError(t, err)
+
+ assert.Equal(t,
+ StringLocation("test"),
+ location,
+ )
+ assert.Equal(t, "", qualifiedIdentifier)
})
- t.Run("missing qualified identifier", func(t *testing.T) {
+ t.Run("invalid prefix", func(t *testing.T) {
t.Parallel()
diff --git a/runtime/common/transactionlocation.go b/runtime/common/transactionlocation.go
index 30da5bbd28..29ed8d230e 100644
--- a/runtime/common/transactionlocation.go
+++ b/runtime/common/transactionlocation.go
@@ -70,6 +70,10 @@ func (l TransactionLocation) Description() string {
return fmt.Sprintf("transaction with ID %s", hex.EncodeToString(l[:]))
}
+func (l TransactionLocation) ID() string {
+ return fmt.Sprintf("%s.%s", TransactionLocationPrefix, l)
+}
+
func (l TransactionLocation) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
Type string
diff --git a/runtime/common/transactionlocation_test.go b/runtime/common/transactionlocation_test.go
index d9ad931164..77e41b6980 100644
--- a/runtime/common/transactionlocation_test.go
+++ b/runtime/common/transactionlocation_test.go
@@ -58,6 +58,22 @@ func TestTransactionLocation_TypeID(t *testing.T) {
)
}
+func TestTransactionLocation_ID(t *testing.T) {
+
+ t.Parallel()
+
+ location, _, err := decodeTransactionLocationTypeID(
+ nil,
+ "t.0102000000000000000000000000000000000000000000000000000000000000.Bar.Baz",
+ )
+ require.NoError(t, err)
+
+ assert.Equal(t,
+ "t.0102000000000000000000000000000000000000000000000000000000000000",
+ location.ID(),
+ )
+}
+
func TestDecodeTransactionLocationTypeID(t *testing.T) {
t.Parallel()
@@ -89,10 +105,10 @@ func TestDecodeTransactionLocationTypeID(t *testing.T) {
TransactionLocation{0x1, 0x2},
location,
)
- assert.Empty(t, qualifiedIdentifier)
+ assert.Equal(t, "", qualifiedIdentifier)
})
- t.Run("missing qualified identifier", func(t *testing.T) {
+ t.Run("invalid prefix", func(t *testing.T) {
t.Parallel()
diff --git a/runtime/contract_test.go b/runtime/contract_test.go
index 1b90d4450e..07ea41f7ea 100644
--- a/runtime/contract_test.go
+++ b/runtime/contract_test.go
@@ -177,24 +177,24 @@ func TestRuntimeContract(t *testing.T) {
log: func(message string) {
loggedMessages = append(loggedMessages, message)
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- require.Equal(t, tc.name, name)
- assert.Equal(t, signerAddress, address)
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
+ require.Equal(t, tc.name, location.Name)
+ assert.Equal(t, signerAddress, location.Address)
deployedCode = code
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- if name == tc.name {
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
+ if location.Name == tc.name {
return deployedCode, nil
}
return nil, nil
},
- removeAccountContractCode: func(address Address, name string) error {
- require.Equal(t, tc.name, name)
- assert.Equal(t, signerAddress, address)
+ removeAccountContractCode: func(location common.AddressLocation) error {
+ require.Equal(t, tc.name, location.Name)
+ assert.Equal(t, signerAddress, location.Address)
deployedCode = nil
@@ -662,27 +662,15 @@ func TestRuntimeImportMultipleContracts(t *testing.T) {
getSigningAccounts: func() ([]Address, error) {
return []Address{common.MustBytesToAddress([]byte{0x1})}, nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
code = accountCodes[location]
return code, nil
},
- removeAccountContractCode: func(address Address, name string) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ removeAccountContractCode: func(location common.AddressLocation) error {
delete(accountCodes, location)
return nil
},
diff --git a/runtime/contract_update_test.go b/runtime/contract_update_test.go
index 8a803bc528..24610c3d1b 100644
--- a/runtime/contract_update_test.go
+++ b/runtime/contract_update_test.go
@@ -58,18 +58,10 @@ func TestContractUpdateWithDependencies(t *testing.T) {
return []Address{signerAccount}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
@@ -268,18 +260,10 @@ func TestContractUpdateWithPrecedingIdentifiers(t *testing.T) {
return []Address{signerAccount}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
diff --git a/runtime/contract_update_validation_test.go b/runtime/contract_update_validation_test.go
index 7aac70d9b8..2048097a42 100644
--- a/runtime/contract_update_validation_test.go
+++ b/runtime/contract_update_validation_test.go
@@ -93,26 +93,14 @@ func newContractDeploymentTransactor(t *testing.T) func(code string) error {
return []Address{common.MustBytesToAddress([]byte{0x42})}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
- removeAccountContractCode: func(address Address, name string) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ removeAccountContractCode: func(location common.AddressLocation) error {
delete(accountCodes, location)
return nil
},
@@ -2163,26 +2151,14 @@ func TestRuntimeContractUpdateConformanceChanges(t *testing.T) {
return []Address{address}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
- removeAccountContractCode: func(address Address, name string) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ removeAccountContractCode: func(location common.AddressLocation) error {
delete(accountCodes, location)
return nil
},
@@ -2280,26 +2256,14 @@ func TestRuntimeContractUpdateProgramCaching(t *testing.T) {
return []Address{address}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
- removeAccountContractCode: func(address Address, name string) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ removeAccountContractCode: func(location common.AddressLocation) error {
delete(accountCodes, location)
return nil
},
diff --git a/runtime/convertValues.go b/runtime/convertValues.go
index ecdf78428f..e5393c31d1 100644
--- a/runtime/convertValues.go
+++ b/runtime/convertValues.go
@@ -211,6 +211,8 @@ func exportValueWithInterpreter(
)
case interpreter.AddressValue:
return cadence.NewMeteredAddress(inter, v), nil
+ case interpreter.PathLinkValue:
+ return exportPathLinkValue(v, inter), nil
case interpreter.PathValue:
return exportPathValue(inter, v), nil
case interpreter.TypeValue:
@@ -583,6 +585,12 @@ func exportDictionaryValue(
return dictionary.WithType(exportType), err
}
+func exportPathLinkValue(v interpreter.PathLinkValue, inter *interpreter.Interpreter) cadence.PathLink {
+ path := exportPathValue(inter, v.TargetPath)
+ ty := string(inter.MustConvertStaticToSemaType(v.Type).ID())
+ return cadence.NewMeteredLink(inter, path, ty)
+}
+
func exportPathValue(gauge common.MemoryGauge, v interpreter.PathValue) cadence.Path {
domain := v.Domain.Identifier()
common.UseMemory(gauge, common.MemoryUsage{
@@ -802,6 +810,8 @@ func (i valueImporter) importValue(value cadence.Value, expectedType sema.Type)
return nil, errors.NewDefaultUserError("cannot import contract")
case cadence.Function:
return nil, errors.NewDefaultUserError("cannot import function")
+ case cadence.PathLink:
+ return nil, errors.NewDefaultUserError("cannot import link")
default:
// This means the implementation has unhandled types.
// Hence, return an internal error
diff --git a/runtime/convertValues_test.go b/runtime/convertValues_test.go
index 00d2128772..cde658a38f 100644
--- a/runtime/convertValues_test.go
+++ b/runtime/convertValues_test.go
@@ -824,6 +824,17 @@ func TestImportValue(t *testing.T) {
Identifier: "foo",
},
},
+ {
+ label: "Link (invalid)",
+ value: cadence.PathLink{
+ TargetPath: cadence.Path{
+ Domain: "storage",
+ Identifier: "test",
+ },
+ BorrowType: "Int",
+ },
+ expected: nil,
+ },
{
label: "Capability (invalid)",
value: cadence.StorageCapability{
@@ -2094,6 +2105,91 @@ func TestExportStorageCapabilityValue(t *testing.T) {
})
}
+func TestExportPathLinkValue(t *testing.T) {
+
+ t.Parallel()
+
+ t.Run("Int", func(t *testing.T) {
+
+ link := interpreter.PathLinkValue{
+ TargetPath: interpreter.PathValue{
+ Domain: common.PathDomainStorage,
+ Identifier: "foo",
+ },
+ Type: interpreter.PrimitiveStaticTypeInt,
+ }
+
+ actual, err := exportValueWithInterpreter(
+ link,
+ newTestInterpreter(t),
+ interpreter.EmptyLocationRange,
+ seenReferences{},
+ )
+ require.NoError(t, err)
+
+ expected := cadence.PathLink{
+ TargetPath: cadence.Path{
+ Domain: "storage",
+ Identifier: "foo",
+ },
+ BorrowType: "Int",
+ }
+
+ assert.Equal(t, expected, actual)
+ })
+
+ t.Run("Struct", func(t *testing.T) {
+
+ const code = `
+ struct S {}
+ `
+ program, err := parser.ParseProgram(nil, []byte(code), parser.Config{})
+ require.NoError(t, err)
+
+ checker, err := sema.NewChecker(
+ program,
+ TestLocation,
+ nil,
+ &sema.Config{
+ AccessCheckMode: sema.AccessCheckModeNotSpecifiedUnrestricted,
+ },
+ )
+ require.NoError(t, err)
+
+ err = checker.Check()
+ require.NoError(t, err)
+
+ inter := newTestInterpreter(t)
+ inter.Program = interpreter.ProgramFromChecker(checker)
+
+ capability := interpreter.PathLinkValue{
+ TargetPath: interpreter.PathValue{
+ Domain: common.PathDomainStorage,
+ Identifier: "foo",
+ },
+ Type: interpreter.NewCompositeStaticTypeComputeTypeID(inter, TestLocation, "S"),
+ }
+
+ actual, err := exportValueWithInterpreter(
+ capability,
+ inter,
+ interpreter.EmptyLocationRange,
+ seenReferences{},
+ )
+ require.NoError(t, err)
+
+ expected := cadence.PathLink{
+ TargetPath: cadence.Path{
+ Domain: "storage",
+ Identifier: "foo",
+ },
+ BorrowType: "S.test.S",
+ }
+
+ assert.Equal(t, expected, actual)
+ })
+}
+
func TestExportCompositeValueWithFunctionValueField(t *testing.T) {
t.Parallel()
diff --git a/runtime/coverage.go b/runtime/coverage.go
index a3dc369091..cd01067ddb 100644
--- a/runtime/coverage.go
+++ b/runtime/coverage.go
@@ -38,6 +38,10 @@ type LocationCoverage struct {
// AddLineHit increments the hit count for the given line.
func (c *LocationCoverage) AddLineHit(line int) {
+ // Lines below 1 are dropped.
+ if line < 1 {
+ return
+ }
c.LineHits[line]++
}
@@ -100,13 +104,13 @@ func NewLocationCoverage(lineHits map[int]int) *LocationCoverage {
}
// CoverageReport collects coverage information per location.
-// It keeps track of inspected programs per location, and can
-// also exclude locations from coverage collection.
+// It keeps track of inspected locations, and can also exclude
+// locations from coverage collection.
type CoverageReport struct {
// Contains a *LocationCoverage per location.
Coverage map[common.Location]*LocationCoverage `json:"-"`
- // Contains an *ast.Program per location.
- Programs map[common.Location]*ast.Program `json:"-"`
+ // Contains locations whose programs are already inspected.
+ Locations map[common.Location]struct{} `json:"-"`
// Contains locations excluded from coverage collection.
ExcludedLocations map[common.Location]struct{} `json:"-"`
}
@@ -127,13 +131,13 @@ func (r *CoverageReport) IsLocationExcluded(location Location) bool {
// AddLineHit increments the hit count for the given line, on the given
// location. The method call is a NO-OP in two cases:
// - If the location is excluded from coverage collection
-// - If the location's *ast.Program, has not been inspected
+// - If the location has not been inspected for its statements
func (r *CoverageReport) AddLineHit(location Location, line int) {
if r.IsLocationExcluded(location) {
return
}
- if !r.IsProgramInspected(location) {
+ if !r.IsLocationInspected(location) {
return
}
@@ -142,15 +146,19 @@ func (r *CoverageReport) AddLineHit(location Location, line int) {
}
// InspectProgram inspects the elements of the given *ast.Program, and counts its
-// statements. If inspection is successful, the *ast.Program is marked as inspected.
+// statements. If inspection is successful, the location is marked as inspected.
// If the given location is excluded from coverage collection, the method call
// results in a NO-OP.
func (r *CoverageReport) InspectProgram(location Location, program *ast.Program) {
if r.IsLocationExcluded(location) {
return
}
- r.Programs[location] = program
+ r.Locations[location] = struct{}{}
lineHits := make(map[int]int, 0)
+ recordLine := func(hasPosition ast.HasPosition) {
+ line := hasPosition.StartPosition().Line
+ lineHits[line] = 0
+ }
var depth int
inspector := ast.NewInspector(program)
@@ -170,8 +178,22 @@ func (r *CoverageReport) InspectProgram(location Location, program *ast.Program)
// However, also track local (i.e. non-top level) variable declarations.
if (isStatement && !isDeclaration) ||
(isVariableDeclaration && depth > 2) {
- line := element.StartPosition().Line
- lineHits[line] = 0
+ recordLine(element)
+ }
+
+ functionBlock, isFunctionBlock := element.(*ast.FunctionBlock)
+ // Track also pre/post conditions defined inside functions.
+ if isFunctionBlock {
+ if functionBlock.PreConditions != nil {
+ for _, condition := range *functionBlock.PreConditions {
+ recordLine(condition.Test)
+ }
+ }
+ if functionBlock.PostConditions != nil {
+ for _, condition := range *functionBlock.PostConditions {
+ recordLine(condition.Test)
+ }
+ }
}
} else {
depth--
@@ -180,63 +202,201 @@ func (r *CoverageReport) InspectProgram(location Location, program *ast.Program)
return true
})
- locationCoverage := NewLocationCoverage(lineHits)
- r.Coverage[location] = locationCoverage
+ r.Coverage[location] = NewLocationCoverage(lineHits)
}
-// IsProgramInspected checks whether the *ast.Program on the given
-// location, has been inspected or not.
-func (r *CoverageReport) IsProgramInspected(location Location) bool {
- _, isInspected := r.Programs[location]
+// IsLocationInspected checks whether the given location,
+// has been inspected or not.
+func (r *CoverageReport) IsLocationInspected(location Location) bool {
+ _, isInspected := r.Locations[location]
return isInspected
}
-// CoveredStatementsPercentage returns a string representation of
-// the covered statements percentage. It is defined as the ratio
-// of total covered lines over total statements, for all locations.
-func (r *CoverageReport) CoveredStatementsPercentage() string {
+// Percentage returns a string representation of the covered statements
+// percentage. It is defined as the ratio of total covered lines over
+// total statements, for all locations.
+func (r *CoverageReport) Percentage() string {
+ totalStatements := r.Statements()
+ totalCoveredLines := r.Hits()
+ return fmt.Sprintf(
+ "%0.1f%%",
+ 100*float64(totalCoveredLines)/float64(totalStatements),
+ )
+}
+
+// String returns a human-friendly message for the covered
+// statements percentage.
+func (r *CoverageReport) String() string {
+ return fmt.Sprintf("Coverage: %v of statements", r.Percentage())
+}
+
+// Reset flushes the collected coverage information for all locations
+// and inspected locations. Excluded locations remain intact.
+func (r *CoverageReport) Reset() {
+ for location := range r.Coverage { // nolint:maprange
+ delete(r.Coverage, location)
+ }
+ for location := range r.Locations { // nolint:maprange
+ delete(r.Locations, location)
+ }
+}
+
+// Merge adds all the collected coverage information to the
+// calling object. Excluded locations are also taken into
+// account.
+func (r *CoverageReport) Merge(other CoverageReport) {
+ for location, locationCoverage := range other.Coverage { // nolint:maprange
+ r.Coverage[location] = locationCoverage
+ }
+ for location, v := range other.Locations { // nolint:maprange
+ r.Locations[location] = v
+ }
+ for location, v := range other.ExcludedLocations { // nolint:maprange
+ r.ExcludedLocations[location] = v
+ }
+}
+
+// ExcludedLocationIDs returns the ID of each excluded location. This
+// is helpful in order to marshal/unmarshal a CoverageReport, without
+// losing any valuable information.
+func (r *CoverageReport) ExcludedLocationIDs() []string {
+ excludedLocationIDs := make([]string, 0, len(r.ExcludedLocations))
+ for location := range r.ExcludedLocations { // nolint:maprange
+ excludedLocationIDs = append(excludedLocationIDs, location.ID())
+ }
+ return excludedLocationIDs
+}
+
+// TotalLocations returns the count of locations included in
+// the CoverageReport. This implies that these locations are:
+// - inspected,
+// - not marked as exlucded.
+func (r *CoverageReport) TotalLocations() int {
+ return len(r.Coverage)
+}
+
+// Statements returns the total count of statements, for all the
+// locations included in the CoverageReport.
+func (r *CoverageReport) Statements() int {
totalStatements := 0
- totalCoveredLines := 0
for _, locationCoverage := range r.Coverage { // nolint:maprange
totalStatements += locationCoverage.Statements
+ }
+ return totalStatements
+}
+
+// Hits returns the total count of covered lines, for all the
+// locations included in the CoverageReport.
+func (r *CoverageReport) Hits() int {
+ totalCoveredLines := 0
+ for _, locationCoverage := range r.Coverage { // nolint:maprange
totalCoveredLines += locationCoverage.CoveredLines()
}
- percentage := fmt.Sprintf(
+ return totalCoveredLines
+}
+
+// Misses returns the total count of non-covered lines, for all
+// the locations included in the CoverageReport.
+func (r *CoverageReport) Misses() int {
+ return r.Statements() - r.Hits()
+}
+
+// Summary returns a CoverageReportSummary object, containing
+// key metrics for a CoverageReport, such as:
+// - Total Locations,
+// - Total Statements,
+// - Total Hits,
+// - Total Misses,
+// - Overall Coverage Percentage.
+func (r *CoverageReport) Summary() CoverageReportSummary {
+ return CoverageReportSummary{
+ Locations: r.TotalLocations(),
+ Statements: r.Statements(),
+ Hits: r.Hits(),
+ Misses: r.Misses(),
+ Coverage: r.Percentage(),
+ }
+}
+
+// Diff computes the incremental diff between the calling object and
+// a new CoverageReport. The returned result is a CoverageReportSummary
+// object.
+//
+// CoverageReportSummary{
+// Locations: 0,
+// Statements: 0,
+// Hits: 2,
+// Misses: -2,
+// Coverage: "100.0%",
+// }
+//
+// The above diff is interpreted as follows:
+// - No diff in locations,
+// - No diff in statements,
+// - Hits increased by 2,
+// - Misses decreased by 2,
+// - Coverage Δ increased by 100.0%.
+func (r *CoverageReport) Diff(other CoverageReport) CoverageReportSummary {
+ baseCoverage := 100 * float64(r.Hits()) / float64(r.Statements())
+ newCoverage := 100 * float64(other.Hits()) / float64(other.Statements())
+ coverageDelta := fmt.Sprintf(
"%0.1f%%",
- 100*float64(totalCoveredLines)/float64(totalStatements),
+ 100*(newCoverage-baseCoverage)/baseCoverage,
)
- return fmt.Sprintf("Coverage: %v of statements", percentage)
+ return CoverageReportSummary{
+ Locations: other.TotalLocations() - r.TotalLocations(),
+ Statements: other.Statements() - r.Statements(),
+ Hits: other.Hits() - r.Hits(),
+ Misses: other.Misses() - r.Misses(),
+ Coverage: coverageDelta,
+ }
+}
+
+// CoverageReportSummary contains key metrics that are derived
+// from a CoverageReport object, such as:
+// - Total Locations,
+// - Total Statements,
+// - Total Hits,
+// - Total Misses,
+// - Overall Coverage Percentage.
+// This metrics can be utilized in various ways, such as a CI
+// plugin/app.
+type CoverageReportSummary struct {
+ Locations int `json:"locations"`
+ Statements int `json:"statements"`
+ Hits int `json:"hits"`
+ Misses int `json:"misses"`
+ Coverage string `json:"coverage"`
}
// NewCoverageReport creates and returns a *CoverageReport.
func NewCoverageReport() *CoverageReport {
return &CoverageReport{
Coverage: map[common.Location]*LocationCoverage{},
- Programs: map[common.Location]*ast.Program{},
+ Locations: map[common.Location]struct{}{},
ExcludedLocations: map[common.Location]struct{}{},
}
}
-// MarshalJSON serializes each common.Location/*LocationCoverage
-// key/value pair on the *CoverageReport.Coverage map.
-func (r *CoverageReport) MarshalJSON() ([]byte, error) {
- type Alias CoverageReport
+type crAlias CoverageReport
- // To avoid the overhead of having the Percentage & MissedLines
- // as fields in the LocationCoverage struct, we simply populate
- // this LC struct, with the corresponding methods, upon marshalling.
- type LC struct {
- LineHits map[int]int `json:"line_hits"`
- MissedLines []int `json:"missed_lines"`
- Statements int `json:"statements"`
- Percentage string `json:"percentage"`
- }
+// To avoid the overhead of having the Percentage & MissedLines
+// as fields in the LocationCoverage struct, we simply populate
+// this lcAlias struct, with the corresponding methods, upon marshalling.
+type lcAlias struct {
+ LineHits map[int]int `json:"line_hits"`
+ MissedLines []int `json:"missed_lines"`
+ Statements int `json:"statements"`
+ Percentage string `json:"percentage"`
+}
- coverage := make(map[string]LC, len(r.Coverage))
+// MarshalJSON serializes each common.Location/*LocationCoverage
+// key/value pair on the *CoverageReport.Coverage map, as well
+// as the IDs on the *CoverageReport.ExcludedLocations map.
+func (r *CoverageReport) MarshalJSON() ([]byte, error) {
+ coverage := make(map[string]lcAlias, len(r.Coverage))
for location, locationCoverage := range r.Coverage { // nolint:maprange
- typeID := location.TypeID(nil, "")
- locationID := typeID[:len(typeID)-1]
- coverage[string(locationID)] = LC{
+ coverage[location.ID()] = lcAlias{
LineHits: locationCoverage.LineHits,
MissedLines: locationCoverage.MissedLines(),
Statements: locationCoverage.Statements,
@@ -244,10 +404,56 @@ func (r *CoverageReport) MarshalJSON() ([]byte, error) {
}
}
return json.Marshal(&struct {
- Coverage map[string]LC `json:"coverage"`
- *Alias
+ Coverage map[string]lcAlias `json:"coverage"`
+ ExcludedLocations []string `json:"excluded_locations"`
+ *crAlias
}{
- Coverage: coverage,
- Alias: (*Alias)(r),
+ Coverage: coverage,
+ ExcludedLocations: r.ExcludedLocationIDs(),
+ crAlias: (*crAlias)(r),
})
}
+
+// UnmarshalJSON deserializes a JSON structure and populates
+// the calling object with the respective *CoverageReport.Coverage &
+// *CoverageReport.ExcludedLocations maps.
+func (r *CoverageReport) UnmarshalJSON(data []byte) error {
+ cr := &struct {
+ Coverage map[string]lcAlias `json:"coverage"`
+ ExcludedLocations []string `json:"excluded_locations"`
+ *crAlias
+ }{
+ crAlias: (*crAlias)(r),
+ }
+
+ if err := json.Unmarshal(data, cr); err != nil {
+ return err
+ }
+
+ for locationID, locationCoverage := range cr.Coverage { // nolint:maprange
+ location, _, err := common.DecodeTypeID(nil, locationID)
+ if err != nil {
+ return err
+ }
+ if location == nil {
+ return fmt.Errorf("invalid Location ID: %s", locationID)
+ }
+ r.Coverage[location] = &LocationCoverage{
+ LineHits: locationCoverage.LineHits,
+ Statements: locationCoverage.Statements,
+ }
+ r.Locations[location] = struct{}{}
+ }
+ for _, locationID := range cr.ExcludedLocations {
+ location, _, err := common.DecodeTypeID(nil, locationID)
+ if err != nil {
+ return err
+ }
+ if location == nil {
+ return fmt.Errorf("invalid Location ID: %s", locationID)
+ }
+ r.ExcludedLocations[location] = struct{}{}
+ }
+
+ return nil
+}
diff --git a/runtime/coverage_test.go b/runtime/coverage_test.go
index 09ebc6474e..9d4a36a7d4 100644
--- a/runtime/coverage_test.go
+++ b/runtime/coverage_test.go
@@ -29,6 +29,7 @@ import (
"github.com/onflow/cadence"
"github.com/onflow/cadence/runtime/common"
"github.com/onflow/cadence/runtime/parser"
+ "github.com/onflow/cadence/runtime/stdlib"
)
func TestNewLocationCoverage(t *testing.T) {
@@ -64,6 +65,8 @@ func TestLocationCoverageAddLineHit(t *testing.T) {
lineHits := map[int]int{3: 0, 4: 0, 5: 0, 7: 0, 9: 0, 11: 0}
locationCoverage := NewLocationCoverage(lineHits)
+ // Lines below 1 are dropped.
+ locationCoverage.AddLineHit(0)
locationCoverage.AddLineHit(3)
locationCoverage.AddLineHit(3)
locationCoverage.AddLineHit(7)
@@ -102,6 +105,7 @@ func TestLocationCoverageCoveredLines(t *testing.T) {
}
func TestLocationCoverageMissedLines(t *testing.T) {
+
t.Parallel()
lineHits := map[int]int{3: 0, 4: 0, 5: 0, 7: 0, 9: 0, 11: 0}
@@ -137,33 +141,532 @@ func TestLocationCoveragePercentage(t *testing.T) {
assert.Equal(t, "100.0%", locationCoverage.Percentage())
}
-func TestNewCoverageReport(t *testing.T) {
+func TestNewCoverageReport(t *testing.T) {
+
+ t.Parallel()
+
+ coverageReport := NewCoverageReport()
+
+ assert.Equal(t, 0, len(coverageReport.Coverage))
+ assert.Equal(t, 0, len(coverageReport.Locations))
+ assert.Equal(t, 0, len(coverageReport.ExcludedLocations))
+}
+
+func TestCoverageReportExcludeLocation(t *testing.T) {
+
+ t.Parallel()
+
+ coverageReport := NewCoverageReport()
+
+ location := common.StringLocation("FooContract")
+ coverageReport.ExcludeLocation(location)
+ // We do not allow duplicate locations
+ coverageReport.ExcludeLocation(location)
+
+ assert.Equal(t, 1, len(coverageReport.ExcludedLocations))
+ assert.Equal(t, true, coverageReport.IsLocationExcluded(location))
+}
+
+func TestCoverageReportInspectProgram(t *testing.T) {
+
+ t.Parallel()
+
+ script := []byte(`
+ pub fun answer(): Int {
+ var i = 0
+ while i < 42 {
+ i = i + 1
+ }
+ return i
+ }
+ `)
+
+ program, err := parser.ParseProgram(nil, script, parser.Config{})
+ require.NoError(t, err)
+
+ coverageReport := NewCoverageReport()
+
+ location := common.StringLocation("AnswerScript")
+ coverageReport.InspectProgram(location, program)
+
+ assert.Equal(t, 1, len(coverageReport.Coverage))
+ assert.Equal(t, 1, len(coverageReport.Locations))
+ assert.Equal(t, true, coverageReport.IsLocationInspected(location))
+}
+
+func TestCoverageReportInspectProgramForExcludedLocation(t *testing.T) {
+
+ t.Parallel()
+
+ script := []byte(`
+ pub fun answer(): Int {
+ var i = 0
+ while i < 42 {
+ i = i + 1
+ }
+ return i
+ }
+ `)
+
+ program, err := parser.ParseProgram(nil, script, parser.Config{})
+ require.NoError(t, err)
+
+ coverageReport := NewCoverageReport()
+
+ location := common.StringLocation("AnswerScript")
+ coverageReport.ExcludeLocation(location)
+ coverageReport.InspectProgram(location, program)
+
+ assert.Equal(t, 0, len(coverageReport.Coverage))
+ assert.Equal(t, 0, len(coverageReport.Locations))
+ assert.Equal(t, false, coverageReport.IsLocationInspected(location))
+}
+
+func TestCoverageReportAddLineHit(t *testing.T) {
+
+ t.Parallel()
+
+ script := []byte(`
+ pub fun answer(): Int {
+ var i = 0
+ while i < 42 {
+ i = i + 1
+ }
+ return i
+ }
+ `)
+
+ program, err := parser.ParseProgram(nil, script, parser.Config{})
+ require.NoError(t, err)
+
+ coverageReport := NewCoverageReport()
+
+ location := common.StringLocation("AnswerScript")
+ coverageReport.InspectProgram(location, program)
+
+ coverageReport.AddLineHit(location, 3)
+ coverageReport.AddLineHit(location, 3)
+ coverageReport.AddLineHit(location, 5)
+
+ locationCoverage := coverageReport.Coverage[location]
+
+ assert.Equal(
+ t,
+ map[int]int{3: 2, 4: 0, 5: 1, 7: 0},
+ locationCoverage.LineHits,
+ )
+ assert.Equal(
+ t,
+ []int{4, 7},
+ locationCoverage.MissedLines(),
+ )
+ assert.Equal(t, 4, locationCoverage.Statements)
+ assert.Equal(t, "50.0%", locationCoverage.Percentage())
+ assert.Equal(t, 2, locationCoverage.CoveredLines())
+}
+
+func TestCoverageReportWithFlowLocation(t *testing.T) {
+
+ t.Parallel()
+
+ script := []byte(`
+ pub fun answer(): Int {
+ var i = 0
+ while i < 42 {
+ i = i + 1
+ }
+ return i
+ }
+ `)
+
+ program, err := parser.ParseProgram(nil, script, parser.Config{})
+ require.NoError(t, err)
+
+ coverageReport := NewCoverageReport()
+
+ location := stdlib.FlowLocation{}
+ coverageReport.InspectProgram(location, program)
+
+ actual, err := json.Marshal(coverageReport)
+ require.NoError(t, err)
+
+ expected := `
+ {
+ "coverage": {
+ "flow": {
+ "line_hits": {
+ "3": 0,
+ "4": 0,
+ "5": 0,
+ "7": 0
+ },
+ "missed_lines": [3, 4, 5, 7],
+ "statements": 4,
+ "percentage": "0.0%"
+ }
+ },
+ "excluded_locations": []
+ }
+ `
+ require.JSONEq(t, expected, string(actual))
+}
+
+func TestCoverageReportWithREPLLocation(t *testing.T) {
+
+ t.Parallel()
+
+ script := []byte(`
+ pub fun answer(): Int {
+ var i = 0
+ while i < 42 {
+ i = i + 1
+ }
+ return i
+ }
+ `)
+
+ program, err := parser.ParseProgram(nil, script, parser.Config{})
+ require.NoError(t, err)
+
+ coverageReport := NewCoverageReport()
+
+ location := common.REPLLocation{}
+ coverageReport.InspectProgram(location, program)
+
+ actual, err := json.Marshal(coverageReport)
+ require.NoError(t, err)
+
+ expected := `
+ {
+ "coverage": {
+ "REPL": {
+ "line_hits": {
+ "3": 0,
+ "4": 0,
+ "5": 0,
+ "7": 0
+ },
+ "missed_lines": [3, 4, 5, 7],
+ "statements": 4,
+ "percentage": "0.0%"
+ }
+ },
+ "excluded_locations": []
+ }
+ `
+ require.JSONEq(t, expected, string(actual))
+}
+
+func TestCoverageReportWithScriptLocation(t *testing.T) {
+
+ t.Parallel()
+
+ script := []byte(`
+ pub fun answer(): Int {
+ var i = 0
+ while i < 42 {
+ i = i + 1
+ }
+ return i
+ }
+ `)
+
+ program, err := parser.ParseProgram(nil, script, parser.Config{})
+ require.NoError(t, err)
+
+ coverageReport := NewCoverageReport()
+
+ location := common.ScriptLocation{0x1, 0x2}
+ coverageReport.InspectProgram(location, program)
+
+ actual, err := json.Marshal(coverageReport)
+ require.NoError(t, err)
+
+ expected := `
+ {
+ "coverage": {
+ "s.0102000000000000000000000000000000000000000000000000000000000000": {
+ "line_hits": {
+ "3": 0,
+ "4": 0,
+ "5": 0,
+ "7": 0
+ },
+ "missed_lines": [3, 4, 5, 7],
+ "statements": 4,
+ "percentage": "0.0%"
+ }
+ },
+ "excluded_locations": []
+ }
+ `
+ require.JSONEq(t, expected, string(actual))
+}
+
+func TestCoverageReportWithStringLocation(t *testing.T) {
+
+ t.Parallel()
+
+ script := []byte(`
+ pub fun answer(): Int {
+ var i = 0
+ while i < 42 {
+ i = i + 1
+ }
+ return i
+ }
+ `)
+
+ program, err := parser.ParseProgram(nil, script, parser.Config{})
+ require.NoError(t, err)
+
+ coverageReport := NewCoverageReport()
+
+ location := common.StringLocation("AnswerScript")
+ coverageReport.InspectProgram(location, program)
+
+ actual, err := json.Marshal(coverageReport)
+ require.NoError(t, err)
+
+ expected := `
+ {
+ "coverage": {
+ "S.AnswerScript": {
+ "line_hits": {
+ "3": 0,
+ "4": 0,
+ "5": 0,
+ "7": 0
+ },
+ "missed_lines": [3, 4, 5, 7],
+ "statements": 4,
+ "percentage": "0.0%"
+ }
+ },
+ "excluded_locations": []
+ }
+ `
+ require.JSONEq(t, expected, string(actual))
+}
+
+func TestCoverageReportWithIdentifierLocation(t *testing.T) {
+
+ t.Parallel()
+
+ script := []byte(`
+ pub fun answer(): Int {
+ var i = 0
+ while i < 42 {
+ i = i + 1
+ }
+ return i
+ }
+ `)
+
+ program, err := parser.ParseProgram(nil, script, parser.Config{})
+ require.NoError(t, err)
+
+ coverageReport := NewCoverageReport()
+
+ location := common.IdentifierLocation("Answer")
+ coverageReport.InspectProgram(location, program)
+
+ actual, err := json.Marshal(coverageReport)
+ require.NoError(t, err)
+
+ expected := `
+ {
+ "coverage": {
+ "I.Answer": {
+ "line_hits": {
+ "3": 0,
+ "4": 0,
+ "5": 0,
+ "7": 0
+ },
+ "missed_lines": [3, 4, 5, 7],
+ "statements": 4,
+ "percentage": "0.0%"
+ }
+ },
+ "excluded_locations": []
+ }
+ `
+ require.JSONEq(t, expected, string(actual))
+}
+
+func TestCoverageReportWithTransactionLocation(t *testing.T) {
+
+ t.Parallel()
+
+ script := []byte(`
+ pub fun answer(): Int {
+ var i = 0
+ while i < 42 {
+ i = i + 1
+ }
+ return i
+ }
+ `)
+
+ program, err := parser.ParseProgram(nil, script, parser.Config{})
+ require.NoError(t, err)
+
+ coverageReport := NewCoverageReport()
+
+ location := common.TransactionLocation{0x1, 0x2}
+ coverageReport.InspectProgram(location, program)
+
+ actual, err := json.Marshal(coverageReport)
+ require.NoError(t, err)
+
+ expected := `
+ {
+ "coverage": {
+ "t.0102000000000000000000000000000000000000000000000000000000000000": {
+ "line_hits": {
+ "3": 0,
+ "4": 0,
+ "5": 0,
+ "7": 0
+ },
+ "missed_lines": [3, 4, 5, 7],
+ "statements": 4,
+ "percentage": "0.0%"
+ }
+ },
+ "excluded_locations": []
+ }
+ `
+ require.JSONEq(t, expected, string(actual))
+}
+
+func TestCoverageReportWithAddressLocation(t *testing.T) {
+
+ t.Parallel()
+
+ script := []byte(`
+ pub fun answer(): Int {
+ var i = 0
+ while i < 42 {
+ i = i + 1
+ }
+ return i
+ }
+ `)
+
+ program, err := parser.ParseProgram(nil, script, parser.Config{})
+ require.NoError(t, err)
+
+ coverageReport := NewCoverageReport()
+
+ location := common.AddressLocation{
+ Address: common.MustBytesToAddress([]byte{1, 2}),
+ Name: "Answer",
+ }
+ coverageReport.InspectProgram(location, program)
+
+ actual, err := json.Marshal(coverageReport)
+ require.NoError(t, err)
+
+ expected := `
+ {
+ "coverage": {
+ "A.0000000000000102.Answer": {
+ "line_hits": {
+ "3": 0,
+ "4": 0,
+ "5": 0,
+ "7": 0
+ },
+ "missed_lines": [3, 4, 5, 7],
+ "statements": 4,
+ "percentage": "0.0%"
+ }
+ },
+ "excluded_locations": []
+ }
+ `
+ require.JSONEq(t, expected, string(actual))
+}
+
+func TestCoverageReportReset(t *testing.T) {
+
+ t.Parallel()
+
+ script := []byte(`
+ pub fun answer(): Int {
+ var i = 0
+ while i < 42 {
+ i = i + 1
+ }
+ return i
+ }
+ `)
+
+ program, err := parser.ParseProgram(nil, script, parser.Config{})
+ require.NoError(t, err)
+
+ coverageReport := NewCoverageReport()
+
+ location := common.StringLocation("AnswerScript")
+ coverageReport.InspectProgram(location, program)
+ coverageReport.AddLineHit(location, 3)
+ coverageReport.AddLineHit(location, 3)
+ coverageReport.AddLineHit(location, 5)
+
+ excludedLocation := common.StringLocation("XLocation")
+ coverageReport.ExcludeLocation(excludedLocation)
+
+ assert.Equal(t, 1, len(coverageReport.Coverage))
+ assert.Equal(t, 1, len(coverageReport.Locations))
+ assert.Equal(t, 1, len(coverageReport.ExcludedLocations))
+ assert.Equal(t, true, coverageReport.IsLocationInspected(location))
+ assert.Equal(t, true, coverageReport.IsLocationExcluded(excludedLocation))
+
+ coverageReport.Reset()
+
+ assert.Equal(t, 0, len(coverageReport.Coverage))
+ assert.Equal(t, 0, len(coverageReport.Locations))
+ assert.Equal(t, 1, len(coverageReport.ExcludedLocations))
+ assert.Equal(t, false, coverageReport.IsLocationInspected(location))
+ assert.Equal(t, true, coverageReport.IsLocationExcluded(excludedLocation))
+}
+
+func TestCoverageReportAddLineHitForExcludedLocation(t *testing.T) {
t.Parallel()
coverageReport := NewCoverageReport()
+ location := common.StringLocation("AnswerScript")
+ coverageReport.ExcludeLocation(location)
+
+ coverageReport.AddLineHit(location, 3)
+ coverageReport.AddLineHit(location, 5)
+
assert.Equal(t, 0, len(coverageReport.Coverage))
- assert.Equal(t, 0, len(coverageReport.Programs))
- assert.Equal(t, 0, len(coverageReport.ExcludedLocations))
+ assert.Equal(t, 0, len(coverageReport.Locations))
+ assert.Equal(t, false, coverageReport.IsLocationInspected(location))
}
-func TestCoverageReportExcludeLocation(t *testing.T) {
+func TestCoverageReportAddLineHitForNonInspectedProgram(t *testing.T) {
t.Parallel()
coverageReport := NewCoverageReport()
- location := common.StringLocation("FooContract")
- coverageReport.ExcludeLocation(location)
- // We do not allow duplicate locations
- coverageReport.ExcludeLocation(location)
+ location := common.StringLocation("AnswerScript")
- assert.Equal(t, 1, len(coverageReport.ExcludedLocations))
- assert.Equal(t, true, coverageReport.IsLocationExcluded(location))
+ coverageReport.AddLineHit(location, 3)
+ coverageReport.AddLineHit(location, 5)
+
+ assert.Equal(t, 0, len(coverageReport.Coverage))
+ assert.Equal(t, 0, len(coverageReport.Locations))
+ assert.Equal(t, false, coverageReport.IsLocationInspected(location))
}
-func TestCoverageReportInspectProgram(t *testing.T) {
+func TestCoverageReportPercentage(t *testing.T) {
t.Parallel()
@@ -184,13 +687,36 @@ func TestCoverageReportInspectProgram(t *testing.T) {
location := common.StringLocation("AnswerScript")
coverageReport.InspectProgram(location, program)
+ coverageReport.AddLineHit(location, 3)
+ coverageReport.AddLineHit(location, 4)
- assert.Equal(t, 1, len(coverageReport.Coverage))
- assert.Equal(t, 1, len(coverageReport.Programs))
- assert.Equal(t, true, coverageReport.IsProgramInspected(location))
+ actual, err := json.Marshal(coverageReport)
+ require.NoError(t, err)
+
+ expected := `
+ {
+ "coverage": {
+ "S.AnswerScript": {
+ "line_hits": {
+ "3": 1,
+ "4": 1,
+ "5": 0,
+ "7": 0
+ },
+ "missed_lines": [5, 7],
+ "statements": 4,
+ "percentage": "50.0%"
+ }
+ },
+ "excluded_locations": []
+ }
+ `
+ require.JSONEq(t, expected, string(actual))
+
+ assert.Equal(t, "50.0%", coverageReport.Percentage())
}
-func TestCoverageReportInspectProgramForExcludedLocation(t *testing.T) {
+func TestCoverageReportString(t *testing.T) {
t.Parallel()
@@ -210,15 +736,42 @@ func TestCoverageReportInspectProgramForExcludedLocation(t *testing.T) {
coverageReport := NewCoverageReport()
location := common.StringLocation("AnswerScript")
- coverageReport.ExcludeLocation(location)
coverageReport.InspectProgram(location, program)
+ coverageReport.AddLineHit(location, 3)
+ coverageReport.AddLineHit(location, 4)
+ coverageReport.AddLineHit(location, 5)
- assert.Equal(t, 0, len(coverageReport.Coverage))
- assert.Equal(t, 0, len(coverageReport.Programs))
- assert.Equal(t, false, coverageReport.IsProgramInspected(location))
+ actual, err := json.Marshal(coverageReport)
+ require.NoError(t, err)
+
+ expected := `
+ {
+ "coverage": {
+ "S.AnswerScript": {
+ "line_hits": {
+ "3": 1,
+ "4": 1,
+ "5": 1,
+ "7": 0
+ },
+ "missed_lines": [7],
+ "statements": 4,
+ "percentage": "75.0%"
+ }
+ },
+ "excluded_locations": []
+ }
+ `
+ require.JSONEq(t, expected, string(actual))
+
+ assert.Equal(
+ t,
+ "Coverage: 75.0% of statements",
+ coverageReport.String(),
+ )
}
-func TestCoverageReportAddLineHit(t *testing.T) {
+func TestCoverageReportDiff(t *testing.T) {
t.Parallel()
@@ -239,59 +792,354 @@ func TestCoverageReportAddLineHit(t *testing.T) {
location := common.StringLocation("AnswerScript")
coverageReport.InspectProgram(location, program)
-
coverageReport.AddLineHit(location, 3)
- coverageReport.AddLineHit(location, 3)
- coverageReport.AddLineHit(location, 5)
+ coverageReport.AddLineHit(location, 4)
- locationCoverage := coverageReport.Coverage[location]
+ summary := coverageReport.Summary()
+
+ actual, err := json.Marshal(summary)
+ require.NoError(t, err)
+
+ expected := `
+ {
+ "coverage": "50.0%",
+ "hits": 2,
+ "locations": 1,
+ "misses": 2,
+ "statements": 4
+ }
+ `
+ require.JSONEq(t, expected, string(actual))
+
+ otherCoverageReport := NewCoverageReport()
+ otherCoverageReport.InspectProgram(location, program)
+ otherCoverageReport.AddLineHit(location, 3)
+ otherCoverageReport.AddLineHit(location, 4)
+ otherCoverageReport.AddLineHit(location, 5)
+ otherCoverageReport.AddLineHit(location, 5)
+ otherCoverageReport.AddLineHit(location, 7)
+
+ diff := coverageReport.Diff(*otherCoverageReport)
+
+ actual, err = json.Marshal(diff)
+ require.NoError(t, err)
+
+ expected = `
+ {
+ "coverage": "100.0%",
+ "hits": 2,
+ "locations": 0,
+ "misses": -2,
+ "statements": 0
+ }
+ `
+ require.JSONEq(t, expected, string(actual))
+}
+
+func TestCoverageReportMerge(t *testing.T) {
+
+ t.Parallel()
+
+ integerTraitsScript := []byte(`
+ pub let specialNumbers: {Int: String} = {
+ 1729: "Harshad",
+ 8128: "Harmonic",
+ 41041: "Carmichael"
+ }
+
+ pub fun addSpecialNumber(_ n: Int, _ trait: String) {
+ specialNumbers[n] = trait
+ }
+
+ pub fun getIntegerTrait(_ n: Int): String {
+ if n < 0 {
+ return "Negative"
+ } else if n == 0 {
+ return "Zero"
+ } else if n < 10 {
+ return "Small"
+ } else if n < 100 {
+ return "Big"
+ } else if n < 1000 {
+ return "Huge"
+ }
+
+ if specialNumbers.containsKey(n) {
+ return specialNumbers[n]!
+ }
+
+ return "Enormous"
+ }
+ `)
+
+ program, err := parser.ParseProgram(nil, integerTraitsScript, parser.Config{})
+ require.NoError(t, err)
+
+ coverageReport := NewCoverageReport()
+
+ location := common.StringLocation("IntegerTraits")
+ coverageReport.InspectProgram(location, program)
+
+ factorialScript := []byte(`
+ pub fun factorial(_ n: Int): Int {
+ pre {
+ n >= 0:
+ "factorial is only defined for integers greater than or equal to zero"
+ }
+ post {
+ result >= 1:
+ "the result must be greater than or equal to 1"
+ }
+
+ if n < 1 {
+ return 1
+ }
+
+ return n * factorial(n - 1)
+ }
+ `)
+
+ otherProgram, err := parser.ParseProgram(nil, factorialScript, parser.Config{})
+ require.NoError(t, err)
+
+ otherCoverageReport := NewCoverageReport()
+
+ otherLocation := common.StringLocation("Factorial")
+ otherCoverageReport.InspectProgram(otherLocation, otherProgram)
+
+ excludedLocation := common.StringLocation("FooContract")
+ otherCoverageReport.ExcludeLocation(excludedLocation)
+
+ coverageReport.Merge(*otherCoverageReport)
+
+ actual, err := json.Marshal(coverageReport)
+ require.NoError(t, err)
+
+ expected := `
+ {
+ "coverage": {
+ "S.Factorial": {
+ "line_hits": {
+ "12": 0,
+ "13": 0,
+ "16": 0,
+ "4": 0,
+ "8": 0
+ },
+ "missed_lines": [4, 8, 12, 13, 16],
+ "statements": 5,
+ "percentage": "0.0%"
+ },
+ "S.IntegerTraits": {
+ "line_hits": {
+ "13": 0,
+ "14": 0,
+ "15": 0,
+ "16": 0,
+ "17": 0,
+ "18": 0,
+ "19": 0,
+ "20": 0,
+ "21": 0,
+ "22": 0,
+ "25": 0,
+ "26": 0,
+ "29": 0,
+ "9": 0
+ },
+ "missed_lines": [9, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 25, 26, 29],
+ "statements": 14,
+ "percentage": "0.0%"
+ }
+ },
+ "excluded_locations": ["S.FooContract"]
+ }
+ `
+ require.JSONEq(t, expected, string(actual))
+}
+
+func TestCoverageReportUnmarshalJSON(t *testing.T) {
+
+ t.Parallel()
+
+ data := `
+ {
+ "coverage": {
+ "S.Factorial": {
+ "line_hits": {
+ "12": 0,
+ "13": 0,
+ "16": 0,
+ "4": 0,
+ "8": 0
+ },
+ "missed_lines": [4, 8, 12, 13, 16],
+ "statements": 5,
+ "percentage": "0.0%"
+ },
+ "S.IntegerTraits": {
+ "line_hits": {
+ "13": 0,
+ "14": 0,
+ "15": 0,
+ "16": 0,
+ "17": 0,
+ "18": 0,
+ "19": 0,
+ "20": 0,
+ "21": 0,
+ "22": 0,
+ "25": 0,
+ "26": 0,
+ "29": 0,
+ "9": 0
+ },
+ "missed_lines": [9, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 25, 26, 29],
+ "statements": 14,
+ "percentage": "0.0%"
+ }
+ },
+ "excluded_locations": ["I.Test"]
+ }
+ `
+
+ coverageReport := NewCoverageReport()
+ err := json.Unmarshal([]byte(data), coverageReport)
+ require.NoError(t, err)
+
+ assert.Equal(t, 2, coverageReport.TotalLocations())
+
+ factorialLocation := common.StringLocation("Factorial")
assert.Equal(
t,
- map[int]int{3: 2, 4: 0, 5: 1, 7: 0},
- locationCoverage.LineHits,
+ 5,
+ coverageReport.Coverage[factorialLocation].Statements,
)
assert.Equal(
t,
- []int{4, 7},
- locationCoverage.MissedLines(),
+ "0.0%",
+ coverageReport.Coverage[factorialLocation].Percentage(),
+ )
+ assert.EqualValues(
+ t,
+ []int{4, 8, 12, 13, 16},
+ coverageReport.Coverage[factorialLocation].MissedLines(),
+ )
+ assert.Equal(
+ t,
+ map[int]int{4: 0, 8: 0, 12: 0, 13: 0, 16: 0},
+ coverageReport.Coverage[factorialLocation].LineHits,
)
- assert.Equal(t, 4, locationCoverage.Statements)
- assert.Equal(t, "50.0%", locationCoverage.Percentage())
- assert.Equal(t, 2, locationCoverage.CoveredLines())
-}
-func TestCoverageReportAddLineHitForExcludedLocation(t *testing.T) {
+ actual, err := json.Marshal(coverageReport)
+ require.NoError(t, err)
- t.Parallel()
+ require.JSONEq(t, data, string(actual))
- coverageReport := NewCoverageReport()
+ integerTraitsLocation := common.StringLocation("IntegerTraits")
- location := common.StringLocation("AnswerScript")
- coverageReport.ExcludeLocation(location)
+ assert.Equal(
+ t,
+ coverageReport.Coverage[integerTraitsLocation].Statements,
+ 14,
+ )
+ assert.Equal(
+ t,
+ "0.0%",
+ coverageReport.Coverage[integerTraitsLocation].Percentage(),
+ )
+ assert.EqualValues(
+ t,
+ []int{9, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 25, 26, 29},
+ coverageReport.Coverage[integerTraitsLocation].MissedLines(),
+ )
+ assert.EqualValues(
+ t,
+ map[int]int{9: 0, 13: 0, 14: 0, 15: 0, 16: 0, 17: 0, 18: 0, 19: 0, 20: 0, 21: 0, 22: 0, 25: 0, 26: 0, 29: 0},
+ coverageReport.Coverage[integerTraitsLocation].LineHits,
+ )
- coverageReport.AddLineHit(location, 3)
- coverageReport.AddLineHit(location, 5)
+ assert.Equal(
+ t,
+ 2,
+ len(coverageReport.Locations),
+ )
- assert.Equal(t, 0, len(coverageReport.Coverage))
- assert.Equal(t, 0, len(coverageReport.Programs))
- assert.Equal(t, false, coverageReport.IsProgramInspected(location))
+ assert.Equal(
+ t,
+ []string{"I.Test"},
+ coverageReport.ExcludedLocationIDs(),
+ )
}
-func TestCoverageReportAddLineHitForNonInspectedProgram(t *testing.T) {
+func TestCoverageReportUnmarshalJSONWithFormatError(t *testing.T) {
t.Parallel()
+ data := "My previous coverage report.txt"
+
coverageReport := NewCoverageReport()
+ err := coverageReport.UnmarshalJSON([]byte(data))
+ require.Error(t, err)
+}
- location := common.StringLocation("AnswerScript")
+func TestCoverageReportUnmarshalJSONWithDecodeLocationError(t *testing.T) {
- coverageReport.AddLineHit(location, 3)
- coverageReport.AddLineHit(location, 5)
+ t.Parallel()
- assert.Equal(t, 0, len(coverageReport.Coverage))
- assert.Equal(t, 0, len(coverageReport.Programs))
- assert.Equal(t, false, coverageReport.IsProgramInspected(location))
+ data := `
+ {
+ "coverage": {
+ "X.Factorial": {
+ "line_hits": {
+ "12": 0,
+ "13": 0,
+ "16": 0,
+ "4": 0,
+ "8": 0
+ },
+ "missed_lines": [4, 8, 12, 13, 16],
+ "statements": 5,
+ "percentage": "0.0%"
+ }
+ },
+ "excluded_locations": ["I.Test"]
+ }
+ `
+
+ coverageReport := NewCoverageReport()
+ err := json.Unmarshal([]byte(data), coverageReport)
+ require.ErrorContains(t, err, "invalid Location ID: X.Factorial")
+}
+
+func TestCoverageReportUnmarshalJSONWithDecodeExcludedLocationError(t *testing.T) {
+
+ t.Parallel()
+
+ data := `
+ {
+ "coverage": {
+ "S.Factorial": {
+ "line_hits": {
+ "12": 0,
+ "13": 0,
+ "16": 0,
+ "4": 0,
+ "8": 0
+ },
+ "missed_lines": [4, 8, 12, 13, 16],
+ "statements": 5,
+ "percentage": "0.0%"
+ }
+ },
+ "excluded_locations": ["XI.Test"]
+ }
+ `
+
+ coverageReport := NewCoverageReport()
+ err := json.Unmarshal([]byte(data), coverageReport)
+ require.ErrorContains(t, err, "invalid Location ID: XI.Test")
}
func TestRuntimeCoverage(t *testing.T) {
@@ -332,6 +1180,23 @@ func TestRuntimeCoverage(t *testing.T) {
return "Enormous"
}
+
+ pub fun factorial(_ n: Int): Int {
+ pre {
+ n >= 0:
+ "factorial is only defined for integers greater than or equal to zero"
+ }
+ post {
+ result >= 1:
+ "the result must be greater than or equal to 1"
+ }
+
+ if n < 1 {
+ return 1
+ }
+
+ return n * factorial(n - 1)
+ }
`)
script := []byte(`
@@ -358,6 +1223,9 @@ func TestRuntimeCoverage(t *testing.T) {
addSpecialNumber(78557, "Sierpinski")
assert("Sierpinski" == getIntegerTrait(78557))
+ factorial(5)
+ factorial(0)
+
return 42
}
`)
@@ -410,10 +1278,15 @@ func TestRuntimeCoverage(t *testing.T) {
"25": 5,
"26": 4,
"29": 1,
+ "34": 7,
+ "38": 7,
+ "42": 7,
+ "43": 2,
+ "46": 5,
"9": 1
},
"missed_lines": [],
- "statements": 14,
+ "statements": 19,
"percentage": "100.0%"
},
"s.0000000000000000000000000000000000000000000000000000000000000000": {
@@ -424,13 +1297,16 @@ func TestRuntimeCoverage(t *testing.T) {
"22": 1,
"23": 1,
"25": 1,
+ "26": 1,
+ "28": 1,
"5": 1
},
"missed_lines": [],
- "statements": 7,
+ "statements": 9,
"percentage": "100.0%"
}
- }
+ },
+ "excluded_locations": []
}
`
require.JSONEq(t, expected, string(actual))
@@ -438,7 +1314,7 @@ func TestRuntimeCoverage(t *testing.T) {
assert.Equal(
t,
"Coverage: 100.0% of statements",
- coverageReport.CoveredStatementsPercentage(),
+ coverageReport.String(),
)
}
@@ -566,7 +1442,8 @@ func TestRuntimeCoverageWithExcludedLocation(t *testing.T) {
"statements": 14,
"percentage": "100.0%"
}
- }
+ },
+ "excluded_locations": ["s.0000000000000000000000000000000000000000000000000000000000000000"]
}
`
require.JSONEq(t, expected, string(actual))
@@ -574,6 +1451,6 @@ func TestRuntimeCoverageWithExcludedLocation(t *testing.T) {
assert.Equal(
t,
"Coverage: 100.0% of statements",
- coverageReport.CoveredStatementsPercentage(),
+ coverageReport.String(),
)
}
diff --git a/runtime/deployedcontract_test.go b/runtime/deployedcontract_test.go
index e514234212..e97b07b383 100644
--- a/runtime/deployedcontract_test.go
+++ b/runtime/deployedcontract_test.go
@@ -73,10 +73,7 @@ func TestDeployedContracts(t *testing.T) {
getSigningAccounts: func() ([]Address, error) {
return []Address{{42}}, nil
},
- getAccountContractCode: func(address Address, name string) ([]byte, error) {
- location := common.AddressLocation{
- Address: address, Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) ([]byte, error) {
return accountCodes[location], nil
},
getAccountContractNames: func(_ Address) ([]string, error) {
@@ -89,10 +86,7 @@ func TestDeployedContracts(t *testing.T) {
emitEvent: func(_ cadence.Event) error {
return nil
},
- updateAccountContractCode: func(address common.Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address, Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
diff --git a/runtime/deployment_test.go b/runtime/deployment_test.go
index 52a5b96673..e29292c155 100644
--- a/runtime/deployment_test.go
+++ b/runtime/deployment_test.go
@@ -161,10 +161,10 @@ func TestRuntimeTransactionWithContractDeployment(t *testing.T) {
getSigningAccounts: func() ([]Address, error) {
return []Address{{42}}, nil
},
- getAccountContractCode: func(_ Address, _ string) (code []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) {
return accountCode, nil
},
- updateAccountContractCode: func(_ Address, _ string, code []byte) error {
+ updateAccountContractCode: func(_ common.AddressLocation, code []byte) error {
accountCode = code
return nil
},
diff --git a/runtime/environment.go b/runtime/environment.go
index 61437c8858..7f38f901b2 100644
--- a/runtime/environment.go
+++ b/runtime/environment.go
@@ -127,6 +127,7 @@ func (e *interpreterEnvironment) newInterpreterConfig() *interpreter.Config {
MemoryGauge: e,
BaseActivation: e.baseActivation,
OnEventEmitted: e.newOnEventEmittedHandler(),
+ OnAccountLinked: e.newOnAccountLinkedHandler(),
InjectedCompositeFieldsHandler: e.newInjectedCompositeFieldsHandler(),
UUIDHandler: e.newUUIDHandler(),
ContractValueHandler: e.newContractValueHandler(),
@@ -259,8 +260,8 @@ func (e *interpreterEnvironment) GetAccountContractNames(address common.Address)
return e.runtimeInterface.GetAccountContractNames(address)
}
-func (e *interpreterEnvironment) GetAccountContractCode(address common.Address, name string) ([]byte, error) {
- return e.runtimeInterface.GetAccountContractCode(address, name)
+func (e *interpreterEnvironment) GetAccountContractCode(location common.AddressLocation) ([]byte, error) {
+ return e.runtimeInterface.GetAccountContractCode(location)
}
func (e *interpreterEnvironment) CreateAccount(payer common.Address) (address common.Address, err error) {
@@ -273,17 +274,11 @@ func (e *interpreterEnvironment) EmitEvent(
values []interpreter.Value,
locationRange interpreter.LocationRange,
) {
- eventFields := make([]exportableValue, 0, len(values))
-
- for _, value := range values {
- eventFields = append(eventFields, newExportableValue(value, inter))
- }
-
emitEventFields(
inter,
locationRange,
eventType,
- eventFields,
+ newExportableValues(inter, values),
e.runtimeInterface.EmitEvent,
)
}
@@ -301,24 +296,23 @@ func (e *interpreterEnvironment) RevokeAccountKey(address common.Address, index
return e.runtimeInterface.RevokeAccountKey(address, index)
}
-func (e *interpreterEnvironment) UpdateAccountContractCode(address common.Address, name string, code []byte) error {
- return e.runtimeInterface.UpdateAccountContractCode(address, name, code)
+func (e *interpreterEnvironment) UpdateAccountContractCode(location common.AddressLocation, code []byte) error {
+ return e.runtimeInterface.UpdateAccountContractCode(location, code)
}
-func (e *interpreterEnvironment) RemoveAccountContractCode(address common.Address, name string) error {
- return e.runtimeInterface.RemoveAccountContractCode(address, name)
+func (e *interpreterEnvironment) RemoveAccountContractCode(location common.AddressLocation) error {
+ return e.runtimeInterface.RemoveAccountContractCode(location)
}
-func (e *interpreterEnvironment) RecordContractRemoval(address common.Address, name string) {
- e.storage.recordContractUpdate(address, name, nil)
+func (e *interpreterEnvironment) RecordContractRemoval(location common.AddressLocation) {
+ e.storage.recordContractUpdate(location, nil)
}
func (e *interpreterEnvironment) RecordContractUpdate(
- address common.Address,
- name string,
+ location common.AddressLocation,
contractValue *interpreter.CompositeValue,
) {
- e.storage.recordContractUpdate(address, name, contractValue)
+ e.storage.recordContractUpdate(location, contractValue)
}
func (e *interpreterEnvironment) TemporarilyRecordCode(location common.AddressLocation, code []byte) {
@@ -564,10 +558,7 @@ func (e *interpreterEnvironment) getProgram(
func (e *interpreterEnvironment) getCode(location common.Location) (code []byte, err error) {
if addressLocation, ok := location.(common.AddressLocation); ok {
errors.WrapPanic(func() {
- code, err = e.runtimeInterface.GetAccountContractCode(
- addressLocation.Address,
- addressLocation.Name,
- )
+ code, err = e.runtimeInterface.GetAccountContractCode(addressLocation)
})
} else {
errors.WrapPanic(func() {
@@ -617,7 +608,7 @@ func (e *interpreterEnvironment) newOnStatementHandler() interpreter.OnStatement
return func(inter *interpreter.Interpreter, statement ast.Statement) {
location := inter.Location
- if !e.coverageReport.IsProgramInspected(location) {
+ if !e.coverageReport.IsLocationInspected(location) {
program := inter.Program.Program
e.coverageReport.InspectProgram(location, program)
}
@@ -765,6 +756,26 @@ func (e *interpreterEnvironment) newOnEventEmittedHandler() interpreter.OnEventE
}
}
+func (e *interpreterEnvironment) newOnAccountLinkedHandler() interpreter.OnAccountLinkedFunc {
+ return func(
+ inter *interpreter.Interpreter,
+ locationRange interpreter.LocationRange,
+ addressValue interpreter.AddressValue,
+ pathValue interpreter.PathValue,
+ ) error {
+ e.EmitEvent(
+ inter,
+ stdlib.AccountLinkedEventType,
+ []interpreter.Value{
+ addressValue,
+ pathValue,
+ },
+ locationRange,
+ )
+ return nil
+ }
+}
+
func (e *interpreterEnvironment) newInjectedCompositeFieldsHandler() interpreter.InjectedCompositeFieldsHandlerFunc {
return func(
inter *interpreter.Interpreter,
diff --git a/runtime/error_test.go b/runtime/error_test.go
index 02998ec546..bc46431590 100644
--- a/runtime/error_test.go
+++ b/runtime/error_test.go
@@ -388,11 +388,7 @@ func TestRuntimeError(t *testing.T) {
}
return
},
- getAccountContractCode: func(address Address, name string) ([]byte, error) {
- location := common.AddressLocation{
- Name: name,
- Address: address,
- }
+ getAccountContractCode: func(location common.AddressLocation) ([]byte, error) {
code := codes[location]
return []byte(code), nil
},
diff --git a/runtime/format/capability.go b/runtime/format/capability.go
index af70a7341f..b5bc057e51 100644
--- a/runtime/format/capability.go
+++ b/runtime/format/capability.go
@@ -35,10 +35,3 @@ func StorageCapability(borrowType string, address string, path string) string {
path,
)
}
-
-func AccountCapability(address string) string {
- return fmt.Sprintf(
- "Capability(address: %s)",
- address,
- )
-}
diff --git a/runtime/ft_test.go b/runtime/ft_test.go
index 4358983860..f1d574017c 100644
--- a/runtime/ft_test.go
+++ b/runtime/ft_test.go
@@ -524,18 +524,10 @@ func BenchmarkRuntimeFungibleTokenTransfer(b *testing.B) {
return []Address{signerAccount}, nil
},
resolveLocation: singleIdentifierLocationResolver(b),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
diff --git a/runtime/import_test.go b/runtime/import_test.go
index 76b3481166..9364254cf6 100644
--- a/runtime/import_test.go
+++ b/runtime/import_test.go
@@ -133,18 +133,10 @@ func TestCheckCyclicImports(t *testing.T) {
return []Address{signerAccount}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) ([]byte, error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) ([]byte, error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
diff --git a/runtime/interface.go b/runtime/interface.go
index 9c8e805cda..e892df9497 100644
--- a/runtime/interface.go
+++ b/runtime/interface.go
@@ -79,11 +79,11 @@ type Interface interface {
// RevokeAccountKey removes a key from an account by index.
RevokeAccountKey(address Address, index int) (*AccountKey, error)
// UpdateAccountContractCode updates the code associated with an account contract.
- UpdateAccountContractCode(address Address, name string, code []byte) (err error)
+ UpdateAccountContractCode(location common.AddressLocation, code []byte) (err error)
// GetAccountContractCode returns the code associated with an account contract.
- GetAccountContractCode(address Address, name string) (code []byte, err error)
+ GetAccountContractCode(location common.AddressLocation) (code []byte, err error)
// RemoveAccountContractCode removes the code associated with an account contract.
- RemoveAccountContractCode(address Address, name string) (err error)
+ RemoveAccountContractCode(location common.AddressLocation) (err error)
// GetSigningAccounts returns the signing accounts.
GetSigningAccounts() ([]Address, error)
// ProgramLog logs program logs.
diff --git a/runtime/interpreter/config.go b/runtime/interpreter/config.go
index bbf5540bb5..f2886ef8a5 100644
--- a/runtime/interpreter/config.go
+++ b/runtime/interpreter/config.go
@@ -64,4 +64,8 @@ type Config struct {
AtreeStorageValidationEnabled bool
// AtreeValueValidationEnabled determines if the validation of atree values is enabled
AtreeValueValidationEnabled bool
+ // AccountLinkingAllowed determines if the account linking function is allowed to be used
+ AccountLinkingAllowed bool
+ // OnAccountLinked is triggered when an account is linked by the program
+ OnAccountLinked OnAccountLinkedFunc
}
diff --git a/runtime/interpreter/errors.go b/runtime/interpreter/errors.go
index 8a23f449c8..ef6c86aed8 100644
--- a/runtime/interpreter/errors.go
+++ b/runtime/interpreter/errors.go
@@ -961,3 +961,18 @@ func (e InvalidAttachmentOperationTargetError) Error() string {
e.Value,
)
}
+
+// AccountLinkingForbiddenError is the error which is reported
+// when a user uses the account link function,
+// but account linking is not allowed
+type AccountLinkingForbiddenError struct {
+ LocationRange
+}
+
+var _ errors.UserError = AccountLinkingForbiddenError{}
+
+func (AccountLinkingForbiddenError) IsUserError() {}
+
+func (e AccountLinkingForbiddenError) Error() string {
+ return "account linking is not allowed"
+}
diff --git a/runtime/interpreter/interpreter.go b/runtime/interpreter/interpreter.go
index aacddfc7d4..9e3393d525 100644
--- a/runtime/interpreter/interpreter.go
+++ b/runtime/interpreter/interpreter.go
@@ -112,6 +112,14 @@ type OnMeterComputationFunc func(
intensity uint,
)
+// OnAccountLinkedFunc is a function that is triggered when an account is linked by the program.
+type OnAccountLinkedFunc func(
+ inter *Interpreter,
+ locationRange LocationRange,
+ address AddressValue,
+ path PathValue,
+) error
+
// InjectedCompositeFieldsHandlerFunc is a function that handles storage reads.
type InjectedCompositeFieldsHandlerFunc func(
inter *Interpreter,
@@ -3777,6 +3785,12 @@ func (interpreter *Interpreter) authAccountLinkAccountFunction(addressValue Addr
func(invocation Invocation) Value {
interpreter := invocation.Interpreter
+ if !interpreter.SharedState.Config.AccountLinkingAllowed {
+ panic(AccountLinkingForbiddenError{
+ LocationRange: invocation.LocationRange,
+ })
+ }
+
newCapabilityPath, ok := invocation.Arguments[0].(PathValue)
if !ok {
panic(errors.NewUnreachableError())
@@ -3802,6 +3816,19 @@ func (interpreter *Interpreter) authAccountLinkAccountFunction(addressValue Addr
accountLinkValue,
)
+ onAccountLinked := interpreter.SharedState.Config.OnAccountLinked
+ if onAccountLinked != nil {
+ err := onAccountLinked(
+ interpreter,
+ invocation.LocationRange,
+ addressValue,
+ newCapabilityPath,
+ )
+ if err != nil {
+ panic(err)
+ }
+ }
+
return NewSomeValueNonCopying(
interpreter,
NewStorageCapabilityValue(
@@ -4746,3 +4773,31 @@ func (interpreter *Interpreter) DecodeTypeInfo(decoder *cbor.StreamDecoder) (atr
func (interpreter *Interpreter) Storage() Storage {
return interpreter.SharedState.Config.Storage
}
+
+// ConfigureAccountLinkingAllowed configures if execution is allowed to use account linking,
+// depending on the occurrence of the pragma declaration #allowAccountLinking.
+//
+// The pragma declaration must appear as a top-level declaration (i.e. not nested in the program),
+// and must appear before all other declarations (i.e. at the top of the program).
+//
+// This requirement is also checked statically.
+//
+// This is a temporary feature, which is planned to get replaced by capability controllers,
+// and a new Account type with entitlements.
+func (interpreter *Interpreter) ConfigureAccountLinkingAllowed() {
+ config := interpreter.SharedState.Config
+
+ config.AccountLinkingAllowed = false
+
+ declarations := interpreter.Program.Program.Declarations()
+ if len(declarations) < 1 {
+ return
+ }
+
+ pragmaDeclaration, isPragma := declarations[0].(*ast.PragmaDeclaration)
+ if !isPragma || !sema.IsAllowAccountLinkingPragma(pragmaDeclaration) {
+ return
+ }
+
+ config.AccountLinkingAllowed = true
+}
diff --git a/runtime/interpreter/storage.go b/runtime/interpreter/storage.go
index 1e3e795499..3eed4fea02 100644
--- a/runtime/interpreter/storage.go
+++ b/runtime/interpreter/storage.go
@@ -65,6 +65,7 @@ func ConvertStoredValue(gauge common.MemoryGauge, value atree.Value) (Value, err
panic(errors.NewUnreachableError())
}
return newArrayValueFromConstructor(gauge, staticType, value.Count(), func() *atree.Array { return value }), nil
+
case *atree.OrderedMap:
typeInfo := value.Type()
switch typeInfo := typeInfo.(type) {
diff --git a/runtime/interpreter/value.go b/runtime/interpreter/value.go
index 2ffff29b06..10fb8bd831 100644
--- a/runtime/interpreter/value.go
+++ b/runtime/interpreter/value.go
@@ -14948,7 +14948,10 @@ func (v *CompositeValue) Clone(interpreter *Interpreter) Value {
return nil, nil, nil
}
- key := MustConvertStoredValue(interpreter, atreeKey).Clone(interpreter)
+ // The key is always interpreter.StringAtreeValue,
+ // an "atree-level string", not an interpreter.Value.
+ // Thus, we do not, and cannot, convert.
+ key := atreeKey
value := MustConvertStoredValue(interpreter, atreeValue).Clone(interpreter)
return key, value, nil
diff --git a/runtime/missingmember_test.go b/runtime/missingmember_test.go
index 9ba4704973..b1e427881e 100644
--- a/runtime/missingmember_test.go
+++ b/runtime/missingmember_test.go
@@ -2040,18 +2040,10 @@ pub contract ItemNFT: NonFungibleToken {
return []Address{signerAddress}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
@@ -3860,18 +3852,10 @@ pub contract AuctionDutch {
return []Address{signerAddress}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
@@ -4692,18 +4676,10 @@ pub contract ExampleMarketplace {
return []Address{signerAddress}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
diff --git a/runtime/parser/comment.go b/runtime/parser/comment.go
index 850446b09d..5dc763e1f4 100644
--- a/runtime/parser/comment.go
+++ b/runtime/parser/comment.go
@@ -29,12 +29,10 @@ func (p *parser) parseBlockComment() (endToken lexer.Token, ok bool) {
switch p.current.Type {
case lexer.TokenBlockCommentStart:
p.next()
- ok = false
depth++
case lexer.TokenBlockCommentContent:
p.next()
- ok = false
case lexer.TokenBlockCommentEnd:
endToken = p.current
diff --git a/runtime/predeclaredvalues_test.go b/runtime/predeclaredvalues_test.go
index acd08dda45..069838164b 100644
--- a/runtime/predeclaredvalues_test.go
+++ b/runtime/predeclaredvalues_test.go
@@ -75,10 +75,10 @@ func TestRuntimePredeclaredValues(t *testing.T) {
return []Address{common.MustBytesToAddress([]byte{0x1})}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(_ Address, _ string) (code []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) {
return accountCode, nil
},
- updateAccountContractCode: func(_ Address, _ string, code []byte) error {
+ updateAccountContractCode: func(_ common.AddressLocation, code []byte) error {
accountCode = code
return nil
},
diff --git a/runtime/program_params_validation_test.go b/runtime/program_params_validation_test.go
index 84516f7840..0ba6e4e0c4 100644
--- a/runtime/program_params_validation_test.go
+++ b/runtime/program_params_validation_test.go
@@ -605,11 +605,7 @@ func TestRuntimeTransactionParameterTypeValidation(t *testing.T) {
runtimeInterface := &testRuntimeInterface{
storage: storage,
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return contracts[location], nil
},
meterMemory: func(_ common.MemoryUsage) error {
diff --git a/runtime/resource_duplicate_test.go b/runtime/resource_duplicate_test.go
index 061c4e1936..6e439a6a34 100644
--- a/runtime/resource_duplicate_test.go
+++ b/runtime/resource_duplicate_test.go
@@ -55,18 +55,10 @@ func TestRuntimeResourceDuplicationWithContractTransfer(t *testing.T) {
return []Address{signerAccount}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
diff --git a/runtime/resourcedictionary_test.go b/runtime/resourcedictionary_test.go
index 7db007b87d..e43d231db1 100644
--- a/runtime/resourcedictionary_test.go
+++ b/runtime/resourcedictionary_test.go
@@ -114,14 +114,14 @@ func TestRuntimeResourceDictionaryValues(t *testing.T) {
runtimeInterface := &testRuntimeInterface{
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(_ Address, _ string) (bytes []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (bytes []byte, err error) {
return accountCode, nil
},
storage: newTestLedger(nil, nil),
getSigningAccounts: func() ([]Address, error) {
return []Address{Address(addressValue)}, nil
},
- updateAccountContractCode: func(_ Address, _ string, code []byte) error {
+ updateAccountContractCode: func(_ common.AddressLocation, code []byte) error {
accountCode = code
return nil
},
@@ -467,7 +467,7 @@ func TestRuntimeResourceDictionaryValues_Nested(t *testing.T) {
runtimeInterface := &testRuntimeInterface{
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(_ Address, _ string) (code []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) {
return accountCode, nil
},
getCode: func(_ Location) (bytes []byte, err error) {
@@ -477,7 +477,7 @@ func TestRuntimeResourceDictionaryValues_Nested(t *testing.T) {
getSigningAccounts: func() ([]Address, error) {
return []Address{Address(addressValue)}, nil
},
- updateAccountContractCode: func(_ Address, _ string, code []byte) error {
+ updateAccountContractCode: func(_ common.AddressLocation, code []byte) error {
accountCode = code
return nil
},
@@ -661,10 +661,10 @@ func TestRuntimeResourceDictionaryValues_DictionaryTransfer(t *testing.T) {
}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(_ Address, _ string) (code []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) {
return accountCode, nil
},
- updateAccountContractCode: func(_ Address, _ string, code []byte) (err error) {
+ updateAccountContractCode: func(_ common.AddressLocation, code []byte) (err error) {
accountCode = code
return nil
},
@@ -798,10 +798,10 @@ func TestRuntimeResourceDictionaryValues_Removal(t *testing.T) {
return []Address{signer}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(_ Address, _ string) (code []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) {
return accountCode, nil
},
- updateAccountContractCode: func(_ Address, _ string, code []byte) (err error) {
+ updateAccountContractCode: func(_ common.AddressLocation, code []byte) (err error) {
accountCode = code
return nil
},
@@ -912,10 +912,10 @@ func TestRuntimeSResourceDictionaryValues_Destruction(t *testing.T) {
return []Address{signer}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(_ Address, _ string) (code []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) {
return accountCode, nil
},
- updateAccountContractCode: func(_ Address, _ string, code []byte) error {
+ updateAccountContractCode: func(_ common.AddressLocation, code []byte) error {
accountCode = code
return nil
},
@@ -1053,10 +1053,10 @@ func TestRuntimeResourceDictionaryValues_Insertion(t *testing.T) {
return []Address{signer}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(_ Address, _ string) (code []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) {
return accountCode, nil
},
- updateAccountContractCode: func(_ Address, _ string, code []byte) error {
+ updateAccountContractCode: func(_ common.AddressLocation, code []byte) error {
accountCode = code
return nil
},
@@ -1206,10 +1206,10 @@ func TestRuntimeResourceDictionaryValues_ValueTransferAndDestroy(t *testing.T) {
return signers, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(_ Address, _ string) (code []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) {
return accountCode, nil
},
- updateAccountContractCode: func(_ Address, _ string, code []byte) error {
+ updateAccountContractCode: func(_ common.AddressLocation, code []byte) error {
accountCode = code
return nil
},
@@ -1340,14 +1340,14 @@ func BenchmarkRuntimeResourceDictionaryValues(b *testing.B) {
runtimeInterface := &testRuntimeInterface{
resolveLocation: singleIdentifierLocationResolver(b),
- getAccountContractCode: func(_ Address, _ string) (bytes []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (bytes []byte, err error) {
return accountCode, nil
},
storage: storage,
getSigningAccounts: func() ([]Address, error) {
return []Address{Address(addressValue)}, nil
},
- updateAccountContractCode: func(_ Address, _ string, code []byte) error {
+ updateAccountContractCode: func(_ common.AddressLocation, code []byte) error {
accountCode = code
return nil
},
diff --git a/runtime/runtime.go b/runtime/runtime.go
index 3cfdf350b1..9352d153f5 100644
--- a/runtime/runtime.go
+++ b/runtime/runtime.go
@@ -315,11 +315,11 @@ func (r *interpreterRuntime) NewTransactionExecutor(script Script, context Conte
}
func (r *interpreterRuntime) ExecuteTransaction(script Script, context Context) (err error) {
- _, err = r.NewTransactionExecutor(script, context).Result()
location := context.Location
if _, ok := location.(common.TransactionLocation); !ok {
return errors.NewUnexpectedError("invalid non-transaction location: %s", location)
}
+ _, err = r.NewTransactionExecutor(script, context).Result()
return err
}
diff --git a/runtime/runtime_memory_metering_test.go b/runtime/runtime_memory_metering_test.go
index d88c218aff..196e4c0d77 100644
--- a/runtime/runtime_memory_metering_test.go
+++ b/runtime/runtime_memory_metering_test.go
@@ -77,7 +77,7 @@ func TestInterpreterAddressLocationMetering(t *testing.T) {
meterMemory: func(usage common.MemoryUsage) error {
return meter.MeterMemory(usage)
},
- getAccountContractCode: func(_ Address, _ string) (code []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) {
return accountCode, nil
},
}
@@ -145,19 +145,11 @@ func TestInterpreterElaborationImportMetering(t *testing.T) {
return []Address{Address(addressValue)}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
code = accountCodes[location]
return code, nil
},
@@ -795,7 +787,7 @@ func TestLogFunctionStringConversionMetering(t *testing.T) {
meterMemory: func(usage common.MemoryUsage) error {
return meter.MeterMemory(usage)
},
- getAccountContractCode: func(_ Address, _ string) (code []byte, err error) {
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCode, nil
},
log: func(s string) {
@@ -1071,3 +1063,149 @@ func TestMemoryMeteringErrors(t *testing.T) {
assert.ErrorIs(t, err, testMemoryError{})
})
}
+
+func TestMeterEncoding(t *testing.T) {
+
+ t.Parallel()
+
+ t.Run("string", func(t *testing.T) {
+
+ t.Parallel()
+
+ rt := newTestInterpreterRuntime()
+ rt.defaultConfig.AtreeValidationEnabled = false
+
+ address := common.MustBytesToAddress([]byte{0x1})
+ storage := newTestLedger(nil, nil)
+ meter := newTestMemoryGauge()
+
+ runtimeInterface := &testRuntimeInterface{
+ storage: storage,
+ getSigningAccounts: func() ([]Address, error) {
+ return []Address{address}, nil
+ },
+ meterMemory: meter.MeterMemory,
+ }
+
+ text := "A quick brown fox jumps over the lazy dog"
+
+ err := rt.ExecuteTransaction(
+ Script{
+ Source: []byte(fmt.Sprintf(`
+ transaction() {
+ prepare(acc: AuthAccount) {
+ var s = "%s"
+ acc.save(s, to:/storage/some_path)
+ }
+ }`,
+ text,
+ )),
+ },
+ Context{
+ Interface: runtimeInterface,
+ Location: common.TransactionLocation{},
+ },
+ )
+
+ require.NoError(t, err)
+ assert.Equal(t, 87, int(meter.getMemory(common.MemoryKindBytes)))
+ })
+
+ t.Run("string in loop", func(t *testing.T) {
+
+ t.Parallel()
+
+ rt := newTestInterpreterRuntime()
+ rt.defaultConfig.AtreeValidationEnabled = false
+
+ address := common.MustBytesToAddress([]byte{0x1})
+ storage := newTestLedger(nil, nil)
+ meter := newTestMemoryGauge()
+
+ runtimeInterface := &testRuntimeInterface{
+ storage: storage,
+ getSigningAccounts: func() ([]Address, error) {
+ return []Address{address}, nil
+ },
+ meterMemory: meter.MeterMemory,
+ }
+
+ text := "A quick brown fox jumps over the lazy dog"
+
+ err := rt.ExecuteTransaction(
+ Script{
+ Source: []byte(fmt.Sprintf(`
+ transaction() {
+ prepare(acc: AuthAccount) {
+ var i = 0
+ var s = "%s"
+ while i<1000 {
+ let path = StoragePath(identifier: "i".concat(i.toString()))!
+ acc.save(s, to: path)
+ i=i+1
+ }
+ }
+ }`,
+ text,
+ )),
+ },
+ Context{
+ Interface: runtimeInterface,
+ Location: common.TransactionLocation{},
+ },
+ )
+
+ require.NoError(t, err)
+ assert.Equal(t, 62787, int(meter.getMemory(common.MemoryKindBytes)))
+ })
+
+ t.Run("composite", func(t *testing.T) {
+
+ t.Parallel()
+
+ rt := newTestInterpreterRuntime()
+ rt.defaultConfig.AtreeValidationEnabled = false
+
+ address := common.MustBytesToAddress([]byte{0x1})
+ storage := newTestLedger(nil, nil)
+ meter := newTestMemoryGauge()
+
+ runtimeInterface := &testRuntimeInterface{
+ storage: storage,
+ getSigningAccounts: func() ([]Address, error) {
+ return []Address{address}, nil
+ },
+ meterMemory: meter.MeterMemory,
+ }
+
+ _, err := rt.ExecuteScript(
+ Script{
+ Source: []byte(`
+ pub fun main() {
+ let acc = getAuthAccount(0x02)
+ var i = 0
+ var f = Foo()
+ while i<1000 {
+ let path = StoragePath(identifier: "i".concat(i.toString()))!
+ acc.save(f, to: path)
+ i=i+1
+ }
+ }
+
+ pub struct Foo {
+ priv var id: Int
+ init() {
+ self.id = 123456789
+ }
+ }`),
+ },
+ Context{
+ Interface: runtimeInterface,
+ Location: common.ScriptLocation{},
+ },
+ )
+
+ require.NoError(t, err)
+ assert.Equal(t, 76941, int(meter.getMemory(common.MemoryKindBytes)))
+ })
+}
diff --git a/runtime/runtime_test.go b/runtime/runtime_test.go
index dfe6404630..ffa1ccdf51 100644
--- a/runtime/runtime_test.go
+++ b/runtime/runtime_test.go
@@ -176,9 +176,9 @@ type testRuntimeInterface struct {
getAccountKey func(address Address, index int) (*stdlib.AccountKey, error)
removeAccountKey func(address Address, index int) (*stdlib.AccountKey, error)
accountKeysCount func(address Address) (uint64, error)
- updateAccountContractCode func(address Address, name string, code []byte) error
- getAccountContractCode func(address Address, name string) (code []byte, err error)
- removeAccountContractCode func(address Address, name string) (err error)
+ updateAccountContractCode func(location common.AddressLocation, code []byte) error
+ getAccountContractCode func(location common.AddressLocation) (code []byte, err error)
+ removeAccountContractCode func(location common.AddressLocation) (err error)
getSigningAccounts func() ([]Address, error)
log func(string)
emitEvent func(cadence.Event) error
@@ -375,12 +375,12 @@ func (i *testRuntimeInterface) RevokeAccountKey(address Address, index int) (*st
return i.removeAccountKey(address, index)
}
-func (i *testRuntimeInterface) UpdateAccountContractCode(address Address, name string, code []byte) (err error) {
+func (i *testRuntimeInterface) UpdateAccountContractCode(location common.AddressLocation, code []byte) (err error) {
if i.updateAccountContractCode == nil {
panic("must specify testRuntimeInterface.updateAccountContractCode")
}
- err = i.updateAccountContractCode(address, name, code)
+ err = i.updateAccountContractCode(location, code)
if err != nil {
return err
}
@@ -390,18 +390,18 @@ func (i *testRuntimeInterface) UpdateAccountContractCode(address Address, name s
return nil
}
-func (i *testRuntimeInterface) GetAccountContractCode(address Address, name string) (code []byte, err error) {
+func (i *testRuntimeInterface) GetAccountContractCode(location common.AddressLocation) (code []byte, err error) {
if i.getAccountContractCode == nil {
panic("must specify testRuntimeInterface.getAccountContractCode")
}
- return i.getAccountContractCode(address, name)
+ return i.getAccountContractCode(location)
}
-func (i *testRuntimeInterface) RemoveAccountContractCode(address Address, name string) (err error) {
+func (i *testRuntimeInterface) RemoveAccountContractCode(location common.AddressLocation) (err error) {
if i.removeAccountContractCode == nil {
panic("must specify testRuntimeInterface.removeAccountContractCode")
}
- return i.removeAccountContractCode(address, name)
+ return i.removeAccountContractCode(location)
}
func (i *testRuntimeInterface) GetSigningAccounts() ([]Address, error) {
@@ -1374,11 +1374,7 @@ func TestRuntimeTransactionWithArguments(t *testing.T) {
return tc.authorizers, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return tc.contracts[location], nil
},
log: func(message string) {
@@ -3300,10 +3296,10 @@ func TestRuntimeContractAccount(t *testing.T) {
return []Address{Address(addressValue)}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(_ Address, _ string) (code []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) {
return accountCode, nil
},
- updateAccountContractCode: func(_ Address, _ string, code []byte) error {
+ updateAccountContractCode: func(_ common.AddressLocation, code []byte) error {
accountCode = code
return nil
},
@@ -3410,10 +3406,10 @@ func TestRuntimeInvokeContractFunction(t *testing.T) {
return []Address{addressValue}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(_ Address, _ string) (code []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) {
return accountCode, nil
},
- updateAccountContractCode: func(_ Address, _ string, code []byte) error {
+ updateAccountContractCode: func(_ common.AddressLocation, code []byte) error {
accountCode = code
return nil
},
@@ -3705,10 +3701,10 @@ func TestRuntimeContractNestedResource(t *testing.T) {
return []Address{addressValue}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(_ Address, _ string) (code []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) {
return accountCode, nil
},
- updateAccountContractCode: func(_ Address, _ string, code []byte) error {
+ updateAccountContractCode: func(_ common.AddressLocation, code []byte) error {
accountCode = code
return nil
},
@@ -3802,10 +3798,10 @@ func TestRuntimeStorageLoadedDestructionConcreteType(t *testing.T) {
return []Address{addressValue}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(_ Address, _ string) (code []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) {
return accountCode, nil
},
- updateAccountContractCode: func(address Address, _ string, code []byte) error {
+ updateAccountContractCode: func(_ common.AddressLocation, code []byte) error {
accountCode = code
return nil
},
@@ -3897,10 +3893,10 @@ func TestRuntimeStorageLoadedDestructionAnyResource(t *testing.T) {
return []Address{addressValue}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(_ Address, _ string) (code []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) {
return accountCode, nil
},
- updateAccountContractCode: func(address Address, _ string, code []byte) error {
+ updateAccountContractCode: func(_ common.AddressLocation, code []byte) error {
accountCode = code
return nil
},
@@ -3995,14 +3991,14 @@ func TestRuntimeStorageLoadedDestructionAfterRemoval(t *testing.T) {
return []Address{addressValue}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(_ Address, _ string) (code []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) {
return accountCode, nil
},
- updateAccountContractCode: func(address Address, _ string, code []byte) error {
+ updateAccountContractCode: func(_ common.AddressLocation, code []byte) error {
accountCode = code
return nil
},
- removeAccountContractCode: func(_ Address, _ string) (err error) {
+ removeAccountContractCode: func(_ common.AddressLocation) (err error) {
accountCode = nil
return nil
},
@@ -4232,18 +4228,10 @@ func TestRuntimeFungibleTokenUpdateAccountCode(t *testing.T) {
return []Address{signerAccount}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) (err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) (err error) {
accountCodes[location] = code
return nil
},
@@ -4377,18 +4365,10 @@ func TestRuntimeFungibleTokenCreateAccount(t *testing.T) {
return []Address{signerAccount}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) (err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) (err error) {
accountCodes[location] = code
return nil
},
@@ -4540,18 +4520,10 @@ func TestRuntimeInvokeStoredInterfaceFunction(t *testing.T) {
return []Address{{0x1}}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
@@ -4861,10 +4833,10 @@ func TestRuntimeStoreIntegerTypes(t *testing.T) {
getSigningAccounts: func() ([]Address, error) {
return []Address{addressValue.ToAddress()}, nil
},
- getAccountContractCode: func(_ Address, _ string) (code []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) {
return accountCode, nil
},
- updateAccountContractCode: func(_ Address, _ string, code []byte) error {
+ updateAccountContractCode: func(_ common.AddressLocation, code []byte) error {
accountCode = code
return nil
},
@@ -4987,18 +4959,10 @@ func TestRuntimeResourceOwnerFieldUseComposite(t *testing.T) {
return []Address{address}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
@@ -5191,19 +5155,11 @@ func TestRuntimeResourceOwnerFieldUseArray(t *testing.T) {
getSigningAccounts: func() ([]Address, error) {
return []Address{address}, nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
@@ -5373,18 +5329,10 @@ func TestRuntimeResourceOwnerFieldUseDictionary(t *testing.T) {
return []Address{address}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
@@ -5691,10 +5639,10 @@ func TestRuntimeContractWriteback(t *testing.T) {
return []Address{Address(addressValue)}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(_ Address, _ string) (code []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) {
return accountCode, nil
},
- updateAccountContractCode: func(_ Address, _ string, code []byte) (err error) {
+ updateAccountContractCode: func(_ common.AddressLocation, code []byte) (err error) {
accountCode = code
return nil
},
@@ -5833,10 +5781,10 @@ func TestRuntimeStorageWriteback(t *testing.T) {
return []Address{Address(addressValue)}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(_ Address, _ string) (code []byte, err error) {
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCode, nil
},
- updateAccountContractCode: func(_ Address, _ string, code []byte) error {
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCode = code
return nil
},
@@ -6146,18 +6094,10 @@ func TestRuntimeDeployCodeCaching(t *testing.T) {
return signerAddresses, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
@@ -6291,18 +6231,10 @@ func TestRuntimeUpdateCodeCaching(t *testing.T) {
return signerAddresses, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
@@ -6534,18 +6466,10 @@ func TestRuntimeProgramsHitForToplevelPrograms(t *testing.T) {
return signerAddresses, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
@@ -6722,10 +6646,10 @@ func TestRuntimeTransaction_ContractUpdate(t *testing.T) {
},
}, nil
},
- getAccountContractCode: func(_ Address, _ string) (code []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) {
return accountCode, nil
},
- updateAccountContractCode: func(_ Address, _ string, code []byte) error {
+ updateAccountContractCode: func(_ common.AddressLocation, code []byte) error {
accountCode = code
return nil
},
@@ -7150,19 +7074,11 @@ func TestRuntimeStackOverflow(t *testing.T) {
return []Address{signerAddress}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = string(code)
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
code = []byte(accountCodes[location])
return code, nil
},
@@ -7341,10 +7257,10 @@ func TestRuntimeInternalErrors(t *testing.T) {
return []Address{addressValue}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(_ Address, _ string) (code []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) {
return accountCode, nil
},
- updateAccountContractCode: func(_ Address, _ string, code []byte) error {
+ updateAccountContractCode: func(_ common.AddressLocation, code []byte) error {
accountCode = code
return nil
},
@@ -7524,10 +7440,11 @@ func TestRuntimeComputationMetring(t *testing.T) {
t.Parallel()
type test struct {
- name string
- code string
- ok bool
- expCompUsed uint
+ name string
+ code string
+ ok bool
+ hits uint
+ intensity uint
}
compLimit := uint(6)
@@ -7538,8 +7455,9 @@ func TestRuntimeComputationMetring(t *testing.T) {
code: `
while true {}
`,
- ok: false,
- expCompUsed: compLimit,
+ ok: false,
+ hits: compLimit,
+ intensity: 6,
},
{
name: "Limited while loop",
@@ -7549,24 +7467,36 @@ func TestRuntimeComputationMetring(t *testing.T) {
i = i + 1
}
`,
- ok: false,
- expCompUsed: compLimit,
+ ok: false,
+ hits: compLimit,
+ intensity: 6,
},
{
name: "statement + createArray + transferArray + too many for-in loop iterations",
code: `
for i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] {}
`,
- ok: false,
- expCompUsed: compLimit,
+ ok: false,
+ hits: compLimit,
+ intensity: 15,
},
{
- name: "statement + createArray + transferArray + some for-in loop iterations",
+ name: "statement + createArray + transferArray + two for-in loop iterations",
code: `
for i in [1, 2] {}
`,
- ok: true,
- expCompUsed: 5,
+ ok: true,
+ hits: 5,
+ intensity: 6,
+ },
+ {
+ name: "statement + functionInvocation + encoding",
+ code: `
+ acc.save("A quick brown fox jumps over the lazy dog", to:/storage/some_path)
+ `,
+ ok: true,
+ hits: 3,
+ intensity: 88,
},
}
@@ -7578,7 +7508,7 @@ func TestRuntimeComputationMetring(t *testing.T) {
fmt.Sprintf(
`
transaction {
- prepare() {
+ prepare(acc: AuthAccount) {
%s
}
}
@@ -7590,19 +7520,22 @@ func TestRuntimeComputationMetring(t *testing.T) {
runtime := newTestInterpreterRuntime()
compErr := errors.New("computation exceeded limit")
- var compUsed uint
+ var hits, totalIntensity uint
meterComputationFunc := func(kind common.ComputationKind, intensity uint) error {
- compUsed++
- if compUsed >= compLimit {
+ hits++
+ totalIntensity += intensity
+ if hits >= compLimit {
return compErr
}
return nil
}
+ address := common.MustBytesToAddress([]byte{0x1})
+
runtimeInterface := &testRuntimeInterface{
storage: newTestLedger(nil, nil),
getSigningAccounts: func() ([]Address, error) {
- return nil, nil
+ return []Address{address}, nil
},
meterComputation: meterComputationFunc,
}
@@ -7628,7 +7561,8 @@ func TestRuntimeComputationMetring(t *testing.T) {
require.ErrorAs(t, err.(Error).Unwrap(), &compErr)
}
- require.Equal(t, test.expCompUsed, compUsed)
+ assert.Equal(t, test.hits, hits)
+ assert.Equal(t, test.intensity, totalIntensity)
})
}
}
@@ -7837,18 +7771,10 @@ func TestRuntimeTypeMismatchErrorMessage(t *testing.T) {
return []Address{signerAccount}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) (err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) (err error) {
accountCodes[location] = code
return nil
},
diff --git a/runtime/script_executor.go b/runtime/script_executor.go
index b430b804e4..ced232ac18 100644
--- a/runtime/script_executor.go
+++ b/runtime/script_executor.go
@@ -228,6 +228,8 @@ func (executor *interpreterScriptExecutor) scriptExecutionFunction() InterpretFu
err = internalErr
})
+ inter.ConfigureAccountLinkingAllowed()
+
values, err := validateArgumentParams(
inter,
executor.environment,
@@ -238,6 +240,7 @@ func (executor *interpreterScriptExecutor) scriptExecutionFunction() InterpretFu
if err != nil {
return nil, err
}
+
return inter.Invoke("main", values...)
}
}
diff --git a/runtime/sema/authaccount_type.go b/runtime/sema/authaccount_type.go
index 4ac83c8ee1..53606d550b 100644
--- a/runtime/sema/authaccount_type.go
+++ b/runtime/sema/authaccount_type.go
@@ -54,6 +54,8 @@ const AuthAccountTypeInboxClaimFunctionName = "claim"
var AuthAccountTypeLinkAccountFunctionType *FunctionType
+var AuthAccountTypeLinkAccountFunctionTypePathParameterType = PrivatePathType
+
// AuthAccountType represents the authorized access to an account.
// Access to an AuthAccount means having full access to its storage, public keys, and code.
// Only signed transactions can get the AuthAccount for an account.
@@ -76,9 +78,11 @@ var AuthAccountType = func() *CompositeType {
AuthAccountTypeLinkAccountFunctionType = &FunctionType{
Parameters: []Parameter{
{
- Label: ArgumentLabelNotRequired,
- Identifier: "newCapabilityPath",
- TypeAnnotation: CapabilityPathTypeAnnotation,
+ Label: ArgumentLabelNotRequired,
+ Identifier: "newCapabilityPath",
+ TypeAnnotation: NewTypeAnnotation(
+ AuthAccountTypeLinkAccountFunctionTypePathParameterType,
+ ),
},
},
ReturnTypeAnnotation: NewTypeAnnotation(
diff --git a/runtime/sema/checker.go b/runtime/sema/checker.go
index ad879b312d..bba2fc9d0f 100644
--- a/runtime/sema/checker.go
+++ b/runtime/sema/checker.go
@@ -121,7 +121,6 @@ type Checker struct {
inInvocation bool
inCreate bool
isChecked bool
- allowAccountLinking bool
}
var _ ast.DeclarationVisitor[struct{}] = &Checker{}
@@ -404,20 +403,18 @@ func (checker *Checker) CheckProgram(program *ast.Program) {
for _, declaration := range declarations {
// A pragma declaration #allowAccountLinking determines
- // if the program is allowed to use the account linking.
+ // if the program is allowed to use account linking.
//
// It must appear as a top-level declaration (i.e. not nested in the program),
// and must appear before all other declarations (i.e. at the top of the program).
//
- // This is a temporary feature, which is planned to get replaced
- // by capability controllers, a new Account type, and account entitlements.
+ // This is a temporary feature, which is planned to get replaced by capability controllers,
+ // and a new Account type with entitlements.
if pragmaDeclaration, isPragma := declaration.(*ast.PragmaDeclaration); isPragma {
if IsAllowAccountLinkingPragma(pragmaDeclaration) {
if rejectAllowAccountLinkingPragma {
checker.reportInvalidNonHeaderPragma(pragmaDeclaration)
- } else {
- checker.allowAccountLinking = true
}
continue
}
@@ -2059,17 +2056,20 @@ func (checker *Checker) rewritePostConditions(postConditions []*ast.Condition) P
}
for _, extractedExpression := range extractedExpressions {
+ expression := extractedExpression.Expression
+ startPos := expression.StartPosition()
// NOTE: no need to check the before statements or update elaboration here:
// The before statements are visited/checked later
variableDeclaration := ast.NewEmptyVariableDeclaration(checker.memoryGauge)
+ variableDeclaration.StartPos = startPos
variableDeclaration.Identifier = extractedExpression.Identifier
variableDeclaration.Transfer = ast.NewTransfer(
checker.memoryGauge,
ast.TransferOperationCopy,
- ast.EmptyPosition,
+ startPos,
)
- variableDeclaration.Value = extractedExpression.Expression
+ variableDeclaration.Value = expression
beforeStatements = append(beforeStatements,
variableDeclaration,
@@ -2477,8 +2477,7 @@ func (checker *Checker) isAvailableMember(expressionType Type, identifier string
if expressionType == AuthAccountType &&
identifier == AuthAccountTypeLinkAccountFunctionName {
- return checker.Config.AccountLinkingEnabled &&
- checker.allowAccountLinking
+ return checker.Config.AccountLinkingEnabled
}
return true
diff --git a/runtime/sema/gen/main.go b/runtime/sema/gen/main.go
index baba218d47..fb6a932eca 100644
--- a/runtime/sema/gen/main.go
+++ b/runtime/sema/gen/main.go
@@ -34,6 +34,7 @@ import (
"github.com/onflow/cadence/runtime/common"
"github.com/onflow/cadence/runtime/parser"
"github.com/onflow/cadence/runtime/pretty"
+ "github.com/onflow/cadence/runtime/sema"
"github.com/dave/dst"
)
@@ -265,6 +266,7 @@ func (g *generator) addFunctionTypeDeclaration(
ReturnTypeAnnotation: decl.ReturnTypeAnnotation,
ParameterTypeAnnotations: parameterTypeAnnotations,
},
+ decl.ParameterList,
decl.TypeParameterList,
typeParams,
),
@@ -501,7 +503,7 @@ func typeExpr(t ast.Type, typeParams map[string]string) dst.Expr {
}
case *ast.FunctionType:
- return functionTypeExpr(t, nil, typeParams)
+ return functionTypeExpr(t, nil, nil, typeParams)
case *ast.InstantiationType:
typeArguments := t.TypeArguments
@@ -533,6 +535,7 @@ func typeExpr(t ast.Type, typeParams map[string]string) dst.Expr {
func functionTypeExpr(
t *ast.FunctionType,
+ parameters *ast.ParameterList,
typeParameterList *ast.TypeParameterList,
typeParams map[string]string,
) dst.Expr {
@@ -583,16 +586,48 @@ func functionTypeExpr(
if parameterCount > 0 {
parameterExprs := make([]dst.Expr, 0, parameterCount)
- for _, parameterTypeAnnotation := range parameterTypeAnnotations {
+ for parameterIndex, parameterTypeAnnotation := range parameterTypeAnnotations {
+
+ var parameterElements []dst.Expr
+
+ if parameters != nil {
+ parameter := parameters.Parameters[parameterIndex]
+
+ if parameter.Label != "" {
+ var lit dst.Expr
+ if parameter.Label == sema.ArgumentLabelNotRequired {
+ lit = &dst.Ident{
+ Path: "github.com/onflow/cadence/runtime/sema",
+ Name: "ArgumentLabelNotRequired",
+ }
+ } else {
+ lit = goStringLit(parameter.Label)
+ }
+
+ parameterElements = append(
+ parameterElements,
+ goKeyValue("Label", lit),
+ )
+ }
+
+ parameterElements = append(
+ parameterElements,
+ goKeyValue("Identifier", goStringLit(parameter.Identifier.Identifier)),
+ )
+ }
+
+ parameterElements = append(
+ parameterElements,
+ goKeyValue(
+ "TypeAnnotation",
+ typeAnnotationCallExpr(typeExpr(parameterTypeAnnotation.Type, typeParams)),
+ ),
+ )
parameterExpr := &dst.CompositeLit{
- Elts: []dst.Expr{
- goKeyValue(
- "TypeAnnotation",
- typeAnnotationCallExpr(typeExpr(parameterTypeAnnotation.Type, typeParams)),
- ),
- },
+ Elts: parameterElements,
}
+
parameterExpr.Decorations().Before = dst.NewLine
parameterExpr.Decorations().After = dst.NewLine
diff --git a/runtime/sema/gen/testdata/docstrings.golden.go b/runtime/sema/gen/testdata/docstrings.golden.go
index f2ab0176c1..2459e56e5c 100644
--- a/runtime/sema/gen/testdata/docstrings.golden.go
+++ b/runtime/sema/gen/testdata/docstrings.golden.go
@@ -48,6 +48,7 @@ const DocstringsTypeNwnFunctionName = "nwn"
var DocstringsTypeNwnFunctionType = &FunctionType{
Parameters: []Parameter{
{
+ Identifier: "x",
TypeAnnotation: NewTypeAnnotation(IntType),
},
},
diff --git a/runtime/sema/gen/testdata/functions.golden.go b/runtime/sema/gen/testdata/functions.golden.go
index e20426da3f..ebe3835954 100644
--- a/runtime/sema/gen/testdata/functions.golden.go
+++ b/runtime/sema/gen/testdata/functions.golden.go
@@ -22,6 +22,7 @@ package sema
import (
"github.com/onflow/cadence/runtime/ast"
"github.com/onflow/cadence/runtime/common"
+ "github.com/onflow/cadence/runtime/sema"
)
const TestTypeNothingFunctionName = "nothing"
@@ -41,9 +42,12 @@ const TestTypeParamsFunctionName = "params"
var TestTypeParamsFunctionType = &FunctionType{
Parameters: []Parameter{
{
+ Identifier: "a",
TypeAnnotation: NewTypeAnnotation(IntType),
},
{
+ Label: sema.ArgumentLabelNotRequired,
+ Identifier: "b",
TypeAnnotation: NewTypeAnnotation(StringType),
},
},
@@ -73,9 +77,12 @@ const TestTypeParamsAndReturnFunctionName = "paramsAndReturn"
var TestTypeParamsAndReturnFunctionType = &FunctionType{
Parameters: []Parameter{
{
+ Identifier: "a",
TypeAnnotation: NewTypeAnnotation(IntType),
},
{
+ Label: sema.ArgumentLabelNotRequired,
+ Identifier: "b",
TypeAnnotation: NewTypeAnnotation(StringType),
},
},
@@ -141,6 +148,7 @@ var TestTypeTypeParamWithBoundAndParamFunctionType = &FunctionType{
},
Parameters: []Parameter{
{
+ Identifier: "t",
TypeAnnotation: NewTypeAnnotation(&GenericType{
TypeParameter: TestTypeTypeParamWithBoundAndParamFunctionTypeParameterT,
}),
diff --git a/runtime/sharedstate_test.go b/runtime/sharedstate_test.go
index e7ef26e9d6..e4df0d0c04 100644
--- a/runtime/sharedstate_test.go
+++ b/runtime/sharedstate_test.go
@@ -83,27 +83,15 @@ func TestRuntimeSharedState(t *testing.T) {
getSigningAccounts: func() ([]Address, error) {
return []Address{signerAddress}, nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
code = accountCodes[location]
return code, nil
},
- removeAccountContractCode: func(address Address, name string) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ removeAccountContractCode: func(location common.AddressLocation) error {
delete(accountCodes, location)
return nil
},
diff --git a/runtime/stdlib/account.go b/runtime/stdlib/account.go
index 0878099ca4..ae671ee774 100644
--- a/runtime/stdlib/account.go
+++ b/runtime/stdlib/account.go
@@ -1117,7 +1117,7 @@ func newAccountContractsGetNamesFunction(
type AccountContractProvider interface {
// GetAccountContractCode returns the code associated with an account contract.
- GetAccountContractCode(address common.Address, name string) ([]byte, error)
+ GetAccountContractCode(location common.AddressLocation) ([]byte, error)
}
func newAccountContractsGetFunction(
@@ -1138,11 +1138,12 @@ func newAccountContractsGetFunction(
panic(errors.NewUnreachableError())
}
name := nameValue.Str
+ location := common.NewAddressLocation(invocation.Interpreter, address, name)
var code []byte
var err error
errors.WrapPanic(func() {
- code, err = provider.GetAccountContractCode(address, name)
+ code, err = provider.GetAccountContractCode(location)
})
if err != nil {
panic(err)
@@ -1189,6 +1190,7 @@ func newAccountContractsBorrowFunction(
panic(errors.NewUnreachableError())
}
name := nameValue.Str
+ location := common.NewAddressLocation(invocation.Interpreter, address, name)
typeParameterPair := invocation.TypeParameterTypes.Oldest()
if typeParameterPair == nil {
@@ -1206,7 +1208,7 @@ func newAccountContractsBorrowFunction(
var code []byte
var err error
errors.WrapPanic(func() {
- code, err = handler.GetAccountContractCode(address, name)
+ code, err = handler.GetAccountContractCode(location)
})
if err != nil {
panic(err)
@@ -1256,8 +1258,8 @@ type AccountContractAdditionHandler interface {
getAndSetProgram bool,
) (*interpreter.Program, error)
// UpdateAccountContractCode updates the code associated with an account contract.
- UpdateAccountContractCode(address common.Address, name string, code []byte) error
- RecordContractUpdate(address common.Address, name string, value *interpreter.CompositeValue)
+ UpdateAccountContractCode(location common.AddressLocation, code []byte) error
+ RecordContractUpdate(location common.AddressLocation, value *interpreter.CompositeValue)
InterpretContract(
location common.AddressLocation,
program *interpreter.Program,
@@ -1318,7 +1320,9 @@ func newAuthAccountContractsChangeFunction(
}
address := addressValue.ToAddress()
- existingCode, err := handler.GetAccountContractCode(address, contractName)
+ location := common.NewAddressLocation(invocation.Interpreter, address, contractName)
+
+ existingCode, err := handler.GetAccountContractCode(location)
if err != nil {
panic(err)
}
@@ -1349,9 +1353,6 @@ func newAuthAccountContractsChangeFunction(
}
// Check the code
-
- location := common.NewAddressLocation(invocation.Interpreter, address, contractName)
-
handleContractUpdateError := func(err error) {
if err == nil {
return
@@ -1453,7 +1454,7 @@ func newAuthAccountContractsChangeFunction(
// Validate the contract update
if isUpdate {
- oldCode, err := handler.GetAccountContractCode(address, contractName)
+ oldCode, err := handler.GetAccountContractCode(location)
handleContractUpdateError(err)
oldProgram, err := parser.ParseProgram(
@@ -1484,9 +1485,7 @@ func newAuthAccountContractsChangeFunction(
handler,
location,
program,
- declaredName,
code,
- addressValue,
contractType,
constructorArguments,
constructorArgumentTypes,
@@ -1607,9 +1606,7 @@ func updateAccountContractCode(
handler AccountContractAdditionHandler,
location common.AddressLocation,
program *interpreter.Program,
- name string,
code []byte,
- addressValue interpreter.AddressValue,
contractType *sema.CompositeType,
constructorArguments []interpreter.Value,
constructorArgumentTypes []sema.Type,
@@ -1631,8 +1628,6 @@ func updateAccountContractCode(
createContract := contractType != nil && options.createContract
- address := addressValue.ToAddress()
-
var err error
if createContract {
@@ -1640,7 +1635,6 @@ func updateAccountContractCode(
handler,
location,
program,
- address,
contractType,
constructorArguments,
constructorArgumentTypes,
@@ -1653,7 +1647,7 @@ func updateAccountContractCode(
// NOTE: only update account code if contract instantiation succeeded
errors.WrapPanic(func() {
- err = handler.UpdateAccountContractCode(address, name, code)
+ err = handler.UpdateAccountContractCode(location, code)
})
if err != nil {
return err
@@ -1664,8 +1658,7 @@ func updateAccountContractCode(
// until the end of the execution of the program
handler.RecordContractUpdate(
- address,
- name,
+ location,
contractValue,
)
}
@@ -1709,7 +1702,6 @@ func instantiateContract(
handler AccountContractAdditionHandler,
location common.AddressLocation,
program *interpreter.Program,
- address common.Address,
contractType *sema.CompositeType,
constructorArguments []interpreter.Value,
argumentTypes []sema.Type,
@@ -1769,7 +1761,7 @@ func instantiateContract(
program,
contractType.Identifier,
DeployedContractConstructorInvocation{
- Address: address,
+ Address: location.Address,
ContractType: contractType,
ConstructorArguments: constructorArguments,
ArgumentTypes: argumentTypes,
@@ -1781,8 +1773,8 @@ func instantiateContract(
type AccountContractRemovalHandler interface {
EventEmitter
AccountContractProvider
- RemoveAccountContractCode(address common.Address, name string) error
- RecordContractRemoval(address common.Address, name string)
+ RemoveAccountContractCode(location common.AddressLocation) error
+ RecordContractRemoval(location common.AddressLocation)
}
func newAuthAccountContractsRemoveFunction(
@@ -1805,13 +1797,14 @@ func newAuthAccountContractsRemoveFunction(
panic(errors.NewUnreachableError())
}
name := nameValue.Str
+ location := common.NewAddressLocation(invocation.Interpreter, address, name)
// Get the current code
var code []byte
var err error
errors.WrapPanic(func() {
- code, err = handler.GetAccountContractCode(address, name)
+ code, err = handler.GetAccountContractCode(location)
})
if err != nil {
panic(err)
@@ -1839,7 +1832,7 @@ func newAuthAccountContractsRemoveFunction(
}
errors.WrapPanic(func() {
- err = handler.RemoveAccountContractCode(address, name)
+ err = handler.RemoveAccountContractCode(location)
})
if err != nil {
panic(err)
@@ -1848,7 +1841,7 @@ func newAuthAccountContractsRemoveFunction(
// NOTE: the contract recording function delays the write
// until the end of the execution of the program
- handler.RecordContractRemoval(address, name)
+ handler.RecordContractRemoval(location)
codeHashValue := CodeToHashValue(inter, code)
diff --git a/runtime/stdlib/flow.go b/runtime/stdlib/flow.go
index 237dc9aa65..ff8ea53df3 100644
--- a/runtime/stdlib/flow.go
+++ b/runtime/stdlib/flow.go
@@ -74,6 +74,10 @@ func (l FlowLocation) Description() string {
return FlowLocationPrefix
}
+func (l FlowLocation) ID() string {
+ return FlowLocationPrefix
+}
+
func (l FlowLocation) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
Type string
@@ -105,11 +109,6 @@ func decodeFlowLocationTypeID(typeID string) (FlowLocation, string, error) {
parts := strings.SplitN(typeID, ".", 2)
- pieceCount := len(parts)
- if pieceCount == 1 {
- return newError("missing qualified identifier")
- }
-
prefix := parts[0]
if prefix != FlowLocationPrefix {
@@ -121,7 +120,11 @@ func decodeFlowLocationTypeID(typeID string) (FlowLocation, string, error) {
)
}
- qualifiedIdentifier := parts[1]
+ var qualifiedIdentifier string
+ pieceCount := len(parts)
+ if pieceCount > 1 {
+ qualifiedIdentifier = parts[1]
+ }
return FlowLocation{}, qualifiedIdentifier, nil
}
@@ -271,3 +274,14 @@ var AccountInboxClaimedEventType = newFlowEventType(
AccountEventRecipientParameter,
AccountEventNameParameter,
)
+
+var AccountLinkedEventType = newFlowEventType(
+ "AccountLinked",
+ AccountEventAddressParameter,
+ sema.Parameter{
+ Identifier: "path",
+ TypeAnnotation: sema.NewTypeAnnotation(
+ sema.AuthAccountTypeLinkAccountFunctionTypePathParameterType,
+ ),
+ },
+)
diff --git a/runtime/stdlib/flow_test.go b/runtime/stdlib/flow_test.go
index ef90e58512..da19c17a20 100644
--- a/runtime/stdlib/flow_test.go
+++ b/runtime/stdlib/flow_test.go
@@ -78,6 +78,19 @@ func TestFlowLocationTypeID(t *testing.T) {
)
}
+func TestFlowLocationID(t *testing.T) {
+
+ t.Parallel()
+
+ location, _, err := decodeFlowLocationTypeID("flow.Bar.Baz")
+ require.NoError(t, err)
+
+ assert.Equal(t,
+ "flow",
+ location.ID(),
+ )
+}
+
func TestDecodeFlowLocationTypeID(t *testing.T) {
t.Parallel()
@@ -90,15 +103,35 @@ func TestDecodeFlowLocationTypeID(t *testing.T) {
require.EqualError(t, err, "invalid Flow location type ID: missing prefix")
})
- t.Run("missing qualified identifier", func(t *testing.T) {
+ t.Run("missing qualified identifier part", func(t *testing.T) {
+
+ t.Parallel()
+
+ location, qualifiedIdentifier, err := decodeFlowLocationTypeID("flow")
+ require.NoError(t, err)
+
+ assert.Equal(t,
+ FlowLocation{},
+ location,
+ )
+ assert.Equal(t, "", qualifiedIdentifier)
+ })
+
+ t.Run("empty qualified identifier", func(t *testing.T) {
t.Parallel()
- _, _, err := decodeFlowLocationTypeID("flow")
- require.EqualError(t, err, "invalid Flow location type ID: missing qualified identifier")
+ location, qualifiedIdentifier, err := decodeFlowLocationTypeID("flow.")
+ require.NoError(t, err)
+
+ assert.Equal(t,
+ FlowLocation{},
+ location,
+ )
+ assert.Equal(t, "", qualifiedIdentifier)
})
- t.Run("missing qualified identifier", func(t *testing.T) {
+ t.Run("invalid prefix", func(t *testing.T) {
t.Parallel()
diff --git a/runtime/storage.go b/runtime/storage.go
index d0fa5ae48e..c0a41147c9 100644
--- a/runtime/storage.go
+++ b/runtime/storage.go
@@ -161,11 +161,10 @@ func (s *Storage) storeNewStorageMap(address atree.Address, domain string) *inte
}
func (s *Storage) recordContractUpdate(
- address common.Address,
- name string,
+ location common.AddressLocation,
contractValue *interpreter.CompositeValue,
) {
- key := interpreter.NewStorageKey(s.memoryGauge, address, name)
+ key := interpreter.NewStorageKey(s.memoryGauge, location.Address, location.Name)
// NOTE: do NOT delete the map entry,
// otherwise the removal write is lost
@@ -229,6 +228,13 @@ func (s *Storage) Commit(inter *interpreter.Interpreter, commitContractUpdates b
// Commit the underlying slab storage's writes
+ size := s.PersistentSlabStorage.DeltasSizeWithoutTempAddresses()
+ if size > 0 {
+ inter.ReportComputation(common.ComputationKindEncodeValue, uint(size))
+ usage := common.NewBytesMemoryUsage(int(size))
+ common.UseMemory(s.memoryGauge, usage)
+ }
+
deltas := s.PersistentSlabStorage.DeltasWithoutTempAddresses()
common.UseMemory(s.memoryGauge, common.NewAtreeEncodedSlabMemoryUsage(deltas))
diff --git a/runtime/storage_test.go b/runtime/storage_test.go
index 9d566fc615..0128426f2b 100644
--- a/runtime/storage_test.go
+++ b/runtime/storage_test.go
@@ -526,19 +526,11 @@ func TestRuntimePublicCapabilityBorrowTypeConfusion(t *testing.T) {
return []Address{signingAddress}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
code = accountCodes[location]
return code, nil
},
@@ -765,19 +757,11 @@ func TestRuntimeTopShotContractDeployment(t *testing.T) {
return []Address{testAddress}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = string(code)
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
code = []byte(accountCodes[location])
return code, nil
},
@@ -868,19 +852,11 @@ func TestRuntimeTopShotBatchTransfer(t *testing.T) {
return []Address{signerAddress}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = string(code)
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
code = []byte(accountCodes[location])
return code, nil
},
@@ -1156,19 +1132,11 @@ func TestRuntimeBatchMintAndTransfer(t *testing.T) {
return []Address{signerAddress}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = string(code)
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
code = []byte(accountCodes[location])
return code, nil
},
@@ -1522,19 +1490,11 @@ func TestRuntimeStorageReferenceCast(t *testing.T) {
return []Address{signerAddress}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
code = accountCodes[location]
return code, nil
},
@@ -1827,19 +1787,11 @@ func TestRuntimeResourceOwnerChange(t *testing.T) {
return signers, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
code = accountCodes[location]
return code, nil
},
@@ -2241,18 +2193,10 @@ transaction {
return []Address{signerAccount}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
@@ -2377,18 +2321,10 @@ func TestRuntimeReferenceOwnerAccess(t *testing.T) {
return signers, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
@@ -2514,18 +2450,10 @@ func TestRuntimeReferenceOwnerAccess(t *testing.T) {
return []Address{signerAccount}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
@@ -2660,18 +2588,10 @@ func TestRuntimeReferenceOwnerAccess(t *testing.T) {
return []Address{signerAccount}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
@@ -2792,18 +2712,10 @@ func TestRuntimeReferenceOwnerAccess(t *testing.T) {
return []Address{signerAccount}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
@@ -2922,18 +2834,10 @@ func TestRuntimeReferenceOwnerAccess(t *testing.T) {
return []Address{signerAccount}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
return accountCodes[location], nil
},
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
@@ -3061,19 +2965,11 @@ func TestRuntimeStorageEnumCase(t *testing.T) {
return []Address{address}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
code = accountCodes[location]
return code, nil
},
@@ -3287,19 +3183,11 @@ func TestRuntimeStorageInternalAccess(t *testing.T) {
return []Address{address}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
code = accountCodes[location]
return code, nil
},
@@ -3432,20 +3320,11 @@ func TestRuntimeStorageIteration(t *testing.T) {
return []Address{address}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
-
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
if contractIsBroken {
// Contract no longer has the type
return []byte(`pub contract Test {}`), nil
@@ -3566,20 +3445,11 @@ func TestRuntimeStorageIteration(t *testing.T) {
return []Address{address}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
-
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
if contractIsBroken {
// Contract has a syntax problem
return []byte(`BROKEN`), nil
@@ -3702,20 +3572,11 @@ func TestRuntimeStorageIteration(t *testing.T) {
return []Address{address}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
- updateAccountContractCode: func(address Address, name string, code []byte) error {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
+ updateAccountContractCode: func(location common.AddressLocation, code []byte) error {
accountCodes[location] = code
return nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
- location := common.AddressLocation{
- Address: address,
- Name: name,
- }
-
+ getAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
if contractIsBroken {
// Contract has a semantic error. i.e: cannot find `Bar`
return []byte(`pub contract Test {
diff --git a/runtime/tests/checker/account_test.go b/runtime/tests/checker/account_test.go
index 8d78657d66..39c5bd2839 100644
--- a/runtime/tests/checker/account_test.go
+++ b/runtime/tests/checker/account_test.go
@@ -1120,37 +1120,27 @@ func TestCheckAccount_linkAccount(t *testing.T) {
type testCase struct {
domain common.PathDomain
enabled bool
- allowed bool
}
test := func(tc testCase) {
testName := fmt.Sprintf(
- "%s, enabled=%v, allowed=%v",
+ "%s, enabled=%v",
tc.domain.Identifier(),
tc.enabled,
- tc.allowed,
)
t.Run(testName, func(t *testing.T) {
t.Parallel()
- var pragma string
- if tc.allowed {
- pragma = "#allowAccountLinking"
- }
-
code := fmt.Sprintf(`
- %s
-
resource R {}
fun test(authAccount: AuthAccount): Capability<&AuthAccount>? {
return authAccount.linkAccount(/%s/r)
}
`,
- pragma,
tc.domain.Identifier(),
)
@@ -1163,41 +1153,30 @@ func TestCheckAccount_linkAccount(t *testing.T) {
},
)
- if tc.enabled {
- if tc.allowed {
- switch tc.domain {
- case common.PathDomainPrivate, common.PathDomainPublic:
- require.NoError(t, err)
-
- default:
- errs := RequireCheckerErrors(t, err, 1)
+ if !tc.enabled {
+ errs := RequireCheckerErrors(t, err, 1)
- require.IsType(t, &sema.TypeMismatchError{}, errs[0])
- }
- } else {
- errs := RequireCheckerErrors(t, err, 1)
+ require.IsType(t, &sema.NotDeclaredMemberError{}, errs[0])
+ return
+ }
- require.IsType(t, &sema.NotDeclaredMemberError{}, errs[0])
- }
- } else {
+ if tc.domain != common.PathDomainPrivate {
errs := RequireCheckerErrors(t, err, 1)
- require.IsType(t, &sema.NotDeclaredMemberError{}, errs[0])
+ require.IsType(t, &sema.TypeMismatchError{}, errs[0])
+ return
}
+
+ require.NoError(t, err)
})
}
- options := []bool{true, false}
-
- for _, enabled := range options {
- for _, allowed := range options {
- for _, domain := range common.AllPathDomainsByIdentifier {
- test(testCase{
- domain: domain,
- enabled: enabled,
- allowed: allowed,
- })
- }
+ for _, enabled := range []bool{true, false} {
+ for _, domain := range common.AllPathDomainsByIdentifier {
+ test(testCase{
+ domain: domain,
+ enabled: enabled,
+ })
}
}
}
diff --git a/runtime/tests/checker/conditions_test.go b/runtime/tests/checker/conditions_test.go
index 600ebbceb4..12ca315385 100644
--- a/runtime/tests/checker/conditions_test.go
+++ b/runtime/tests/checker/conditions_test.go
@@ -24,6 +24,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "github.com/onflow/cadence/runtime/ast"
"github.com/onflow/cadence/runtime/sema"
)
@@ -520,3 +521,39 @@ func TestCheckConditionCreateBefore(t *testing.T) {
require.ErrorAs(t, errs[0], ¬CallableErr)
require.Equal(t, sema.IntType, notCallableErr.Type)
}
+
+func TestCheckRewrittenPostConditions(t *testing.T) {
+
+ t.Parallel()
+
+ checker, err := ParseAndCheck(t, `
+ fun test(x: Int) {
+ post {
+ before(x) == 0
+ }
+ }
+ `)
+ require.NoError(t, err)
+
+ declarations := checker.Program.Declarations()
+ require.Len(t, declarations, 1)
+ firstDeclaration := declarations[0]
+
+ require.IsType(t, &ast.FunctionDeclaration{}, firstDeclaration)
+ functionDeclaration := firstDeclaration.(*ast.FunctionDeclaration)
+
+ postConditions := functionDeclaration.FunctionBlock.PostConditions
+ postConditionsRewrite := checker.Elaboration.PostConditionsRewrite(postConditions)
+
+ require.Len(t, postConditionsRewrite.RewrittenPostConditions, 1)
+ require.Len(t, postConditionsRewrite.BeforeStatements, 1)
+
+ beforeStatement := postConditionsRewrite.BeforeStatements[0]
+
+ ast.Inspect(beforeStatement, func(element ast.Element) bool {
+ if element != nil {
+ assert.Positive(t, element.StartPosition().Line)
+ }
+ return true
+ })
+}
diff --git a/runtime/tests/checker/pragma_test.go b/runtime/tests/checker/pragma_test.go
index abfa2c0c20..07a9ca9f39 100644
--- a/runtime/tests/checker/pragma_test.go
+++ b/runtime/tests/checker/pragma_test.go
@@ -113,6 +113,19 @@ func TestCheckAllowAccountLinkingPragma(t *testing.T) {
require.NoError(t, err)
})
+ t.Run("top-level, after other pragmas", func(t *testing.T) {
+ t.Parallel()
+
+ _, err := ParseAndCheck(t, `
+ #someOtherPragma
+ #allowAccountLinking
+
+ let x = 1
+ `)
+ errs := RequireCheckerErrors(t, err, 1)
+ assert.IsType(t, &sema.InvalidPragmaError{}, errs[0])
+ })
+
t.Run("top-level, after other declarations", func(t *testing.T) {
t.Parallel()
diff --git a/runtime/tests/fuzz/crashers_test.go b/runtime/tests/fuzz/crashers_test.go
index bcfcc8aba9..c24a5cff48 100644
--- a/runtime/tests/fuzz/crashers_test.go
+++ b/runtime/tests/fuzz/crashers_test.go
@@ -34,14 +34,11 @@ func TestCrashers(t *testing.T) {
t.Parallel()
- f, err := os.Open(crashersDir)
+ files, err := os.ReadDir(crashersDir)
if err != nil {
return
}
- files, err := f.Readdir(-1)
- _ = f.Close()
-
for _, file := range files {
name := file.Name()
diff --git a/runtime/tests/interpreter/capability_test.go b/runtime/tests/interpreter/capability_test.go
index 2d6dd575cc..28517c2f1e 100644
--- a/runtime/tests/interpreter/capability_test.go
+++ b/runtime/tests/interpreter/capability_test.go
@@ -473,30 +473,26 @@ func TestInterpretCapability_borrow(t *testing.T) {
`
#allowAccountLinking
- fun link() {
- account.linkAccount(/public/acct)
+ fun link(): Capability {
+ return account.linkAccount(/private/acct)!
}
- fun address(_ path: CapabilityPath): Address {
- return account.getCapability(path).borrow<&AuthAccount>()!.address
+ fun address(_ cap: Capability): Address {
+ return cap.borrow<&AuthAccount>()!.address
}
- fun borrow(): Address {
- return address(/public/acct)
+ fun borrow(_ cap: Capability): Address {
+ return address(cap)
}
- fun borrowAuth(): auth &AuthAccount? {
- return account.getCapability(/public/acct).borrow()
+ fun borrowAuth(_ cap: Capability): auth &AuthAccount? {
+ return cap.borrow()
}
- fun nonExistent(): Address {
- return address(/public/nonExistent)
- }
-
- fun unlinkAfterBorrow(): Address {
- let ref = account.getCapability(/public/acct).borrow<&AuthAccount>()!
+ fun unlinkAfterBorrow(_ cap: Capability): Address {
+ let ref = cap.borrow<&AuthAccount>()!
- account.unlink(/public/acct)
+ account.unlink(/private/acct)
return ref.address
}
@@ -508,12 +504,12 @@ func TestInterpretCapability_borrow(t *testing.T) {
// link
- _, err := inter.Invoke("link")
+ capability, err := inter.Invoke("link")
require.NoError(t, err)
t.Run("borrow", func(t *testing.T) {
- value, err := inter.Invoke("borrow")
+ value, err := inter.Invoke("borrow", capability)
require.NoError(t, err)
RequireValuesEqual(t,
@@ -525,23 +521,15 @@ func TestInterpretCapability_borrow(t *testing.T) {
t.Run("borrowAuth", func(t *testing.T) {
- value, err := inter.Invoke("borrowAuth")
+ value, err := inter.Invoke("borrowAuth", capability)
require.NoError(t, err)
require.Equal(t, interpreter.NilValue{}, value)
})
- t.Run("nonExistent", func(t *testing.T) {
-
- _, err := inter.Invoke("nonExistent")
- RequireError(t, err)
-
- require.ErrorAs(t, err, &interpreter.ForceNilError{})
- })
-
t.Run("unlink after borrow", func(t *testing.T) {
- _, err := inter.Invoke("unlinkAfterBorrow")
+ _, err := inter.Invoke("unlinkAfterBorrow", capability)
RequireError(t, err)
require.ErrorAs(t, err, &interpreter.DereferenceError{})
@@ -922,24 +910,16 @@ func TestInterpretCapability_check(t *testing.T) {
`
#allowAccountLinking
- fun link() {
- account.linkAccount(/public/acct)
- }
-
- fun checkPath(_ path: CapabilityPath): Bool {
- return account.getCapability(path).check<&AuthAccount>()
+ fun link(): Capability {
+ return account.linkAccount(/private/acct)!
}
- fun check(): Bool {
- return checkPath(/public/acct)
+ fun check(_ cap: Capability): Bool {
+ return cap.check<&AuthAccount>()
}
- fun checkAuth(): Bool {
- return account.getCapability(/public/acct).check()
- }
-
- fun nonExistent(): Bool {
- return checkPath(/public/nonExistent)
+ fun checkAuth(_ cap: Capability): Bool {
+ return cap.check()
}
`,
sema.Config{
@@ -949,12 +929,12 @@ func TestInterpretCapability_check(t *testing.T) {
// link
- _, err := inter.Invoke("link")
+ capability, err := inter.Invoke("link")
require.NoError(t, err)
t.Run("check", func(t *testing.T) {
- value, err := inter.Invoke("check")
+ value, err := inter.Invoke("check", capability)
require.NoError(t, err)
require.Equal(t, interpreter.TrueValue, value)
@@ -962,15 +942,7 @@ func TestInterpretCapability_check(t *testing.T) {
t.Run("checkAuth", func(t *testing.T) {
- value, err := inter.Invoke("checkAuth")
- require.NoError(t, err)
-
- require.Equal(t, interpreter.FalseValue, value)
- })
-
- t.Run("nonExistent", func(t *testing.T) {
-
- value, err := inter.Invoke("nonExistent")
+ value, err := inter.Invoke("checkAuth", capability)
require.NoError(t, err)
require.Equal(t, interpreter.FalseValue, value)
diff --git a/runtime/tests/interpreter/interpreter_test.go b/runtime/tests/interpreter/interpreter_test.go
index b60cc3a7b7..7a3ab23df4 100644
--- a/runtime/tests/interpreter/interpreter_test.go
+++ b/runtime/tests/interpreter/interpreter_test.go
@@ -157,6 +157,8 @@ func parseCheckAndInterpretWithOptionsAndMemoryMetering(
require.NoError(t, err)
+ inter.ConfigureAccountLinkingAllowed()
+
err = inter.Interpret()
if err == nil {
diff --git a/runtime/tests/interpreter/memory_metering_test.go b/runtime/tests/interpreter/memory_metering_test.go
index 85f14cbb9e..fdd72fc533 100644
--- a/runtime/tests/interpreter/memory_metering_test.go
+++ b/runtime/tests/interpreter/memory_metering_test.go
@@ -6976,7 +6976,7 @@ func TestInterpretStorageCapabilityValueMetering(t *testing.T) {
pub fun main(account: AuthAccount) {
let r <- create R()
account.save(<-r, to: /storage/r)
- let x = account.link<&R>(/public/capo, target: /storage/r)
+ let x = account.link<&R>(/public/cap, target: /storage/r)
}
`
meter := newTestMemoryGauge()
@@ -7000,7 +7000,7 @@ func TestInterpretStorageCapabilityValueMetering(t *testing.T) {
pub fun main(account: AuthAccount) {
let r <- create R()
account.save(<-r, to: /storage/r)
- let x = account.link<&R>(/public/capo, target: /storage/r)
+ let x = account.link<&R>(/public/cap, target: /storage/r)
let y = [x]
}
@@ -7026,7 +7026,7 @@ func TestInterpretPathLinkValueMetering(t *testing.T) {
resource R {}
pub fun main(account: AuthAccount) {
- account.link<&R>(/public/capo, target: /private/p)
+ account.link<&R>(/public/cap, target: /private/p)
}
`
meter := newTestMemoryGauge()
@@ -7052,7 +7052,7 @@ func TestInterpretAccountLinkValueMetering(t *testing.T) {
#allowAccountLinking
pub fun main(account: AuthAccount) {
- account.linkAccount(/public/capo)
+ account.linkAccount(/private/cap)
}
`
@@ -8705,7 +8705,7 @@ func TestInterpretStorageMapMetering(t *testing.T) {
pub fun main(account: AuthAccount) {
let r <- create R()
account.save(<-r, to: /storage/r)
- account.link<&R>(/public/capo, target: /storage/r)
+ account.link<&R>(/public/cap, target: /storage/r)
account.borrow<&R>(from: /storage/r)
}
`
diff --git a/runtime/tests/interpreter/pragma_test.go b/runtime/tests/interpreter/pragma_test.go
new file mode 100644
index 0000000000..e8121f4ff6
--- /dev/null
+++ b/runtime/tests/interpreter/pragma_test.go
@@ -0,0 +1,107 @@
+/*
+ * 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 interpreter_test
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/onflow/cadence/runtime/sema"
+ "github.com/onflow/cadence/runtime/tests/checker"
+)
+
+func TestInterpretAllowAccountLinkingPragma(t *testing.T) {
+
+ t.Parallel()
+
+ t.Run("top-level, before other declarations", func(t *testing.T) {
+ t.Parallel()
+
+ inter := parseCheckAndInterpret(t, `
+ #allowAccountLinking
+
+ let x = 1
+ `)
+ require.True(t, inter.SharedState.Config.AccountLinkingAllowed)
+ })
+
+ t.Run("top-level, after other pragmas", func(t *testing.T) {
+ t.Parallel()
+
+ inter, err := parseCheckAndInterpretWithOptions(t,
+ `
+ #someOtherPragma
+ #allowAccountLinking
+
+ let x = 1
+ `,
+ ParseCheckAndInterpretOptions{
+ HandleCheckerError: func(err error) {
+ errs := checker.RequireCheckerErrors(t, err, 1)
+ assert.IsType(t, &sema.InvalidPragmaError{}, errs[0])
+ },
+ },
+ )
+ require.NoError(t, err)
+ require.False(t, inter.SharedState.Config.AccountLinkingAllowed)
+ })
+
+ t.Run("top-level, after other declarations", func(t *testing.T) {
+ t.Parallel()
+
+ inter, err := parseCheckAndInterpretWithOptions(t,
+ `
+ let x = 1
+
+ #allowAccountLinking
+ `,
+ ParseCheckAndInterpretOptions{
+ HandleCheckerError: func(err error) {
+ errs := checker.RequireCheckerErrors(t, err, 1)
+ assert.IsType(t, &sema.InvalidPragmaError{}, errs[0])
+ },
+ },
+ )
+ require.NoError(t, err)
+ require.False(t, inter.SharedState.Config.AccountLinkingAllowed)
+ })
+
+ t.Run("nested", func(t *testing.T) {
+
+ t.Parallel()
+
+ inter, err := parseCheckAndInterpretWithOptions(t,
+ `
+ fun test() {
+ #allowAccountLinking
+ }
+ `,
+ ParseCheckAndInterpretOptions{
+ HandleCheckerError: func(err error) {
+ errs := checker.RequireCheckerErrors(t, err, 1)
+ require.IsType(t, &sema.InvalidDeclarationError{}, errs[0])
+ },
+ },
+ )
+ require.NoError(t, err)
+ require.False(t, inter.SharedState.Config.AccountLinkingAllowed)
+ })
+}
diff --git a/runtime/tests/interpreter/values_test.go b/runtime/tests/interpreter/values_test.go
index 8536450694..3ad28f0b0a 100644
--- a/runtime/tests/interpreter/values_test.go
+++ b/runtime/tests/interpreter/values_test.go
@@ -50,7 +50,7 @@ var validateAtree = flag.Bool("validateAtree", true, "Enable atree validation")
func TestRandomMapOperations(t *testing.T) {
if !*runSmokeTests {
- t.SkipNow()
+ t.Skip("smoke tests are disabled")
}
t.Parallel()
@@ -357,7 +357,25 @@ func TestRandomMapOperations(t *testing.T) {
t.Run("random insert & remove", func(t *testing.T) {
keyValues := make([][2]interpreter.Value, numberOfValues)
for i := 0; i < numberOfValues; i++ {
- keyValues[i][0] = randomHashableValue(inter)
+ // Generate unique key
+ var key interpreter.Value
+ for {
+ key = randomHashableValue(inter)
+
+ var foundConflict bool
+ for j := 0; j < i; j++ {
+ existingKey := keyValues[j][0]
+ if key.(interpreter.EquatableValue).Equal(inter, interpreter.EmptyLocationRange, existingKey) {
+ foundConflict = true
+ break
+ }
+ }
+ if !foundConflict {
+ break
+ }
+ }
+
+ keyValues[i][0] = key
keyValues[i][1] = randomStorableValue(inter, 0)
}
@@ -497,7 +515,7 @@ func TestRandomMapOperations(t *testing.T) {
func TestRandomArrayOperations(t *testing.T) {
if !*runSmokeTests {
- t.SkipNow()
+ t.Skip("smoke tests are disabled")
}
seed := time.Now().UnixNano()
@@ -861,7 +879,7 @@ func TestRandomArrayOperations(t *testing.T) {
func TestRandomCompositeValueOperations(t *testing.T) {
if !*runSmokeTests {
- t.SkipNow()
+ t.Skip("smoke tests are disabled")
}
seed := time.Now().UnixNano()
diff --git a/runtime/transaction_executor.go b/runtime/transaction_executor.go
index 1591a8d8b0..f7f6ccc192 100644
--- a/runtime/transaction_executor.go
+++ b/runtime/transaction_executor.go
@@ -251,6 +251,8 @@ func (executor *interpreterTransactionExecutor) transactionExecutionFunction(
err = internalErr
})
+ inter.ConfigureAccountLinkingAllowed()
+
values, err := validateArgumentParams(
inter,
executor.environment,
diff --git a/runtime/validation_test.go b/runtime/validation_test.go
index 444f01be25..76e3b0b922 100644
--- a/runtime/validation_test.go
+++ b/runtime/validation_test.go
@@ -52,7 +52,7 @@ func TestRuntimeArgumentImportMissingType(t *testing.T) {
getSigningAccounts: func() ([]Address, error) {
return nil, nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) {
return nil, nil
},
meterMemory: func(_ common.MemoryUsage) error {
@@ -102,7 +102,7 @@ func TestRuntimeArgumentImportMissingType(t *testing.T) {
getSigningAccounts: func() ([]Address, error) {
return nil, nil
},
- getAccountContractCode: func(address Address, name string) (code []byte, err error) {
+ getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) {
return nil, nil
},
meterMemory: func(_ common.MemoryUsage) error {
diff --git a/runtime/value.go b/runtime/value.go
index 0cbad8f48a..8f085a79c8 100644
--- a/runtime/value.go
+++ b/runtime/value.go
@@ -40,6 +40,16 @@ func newExportableValue(v interpreter.Value, inter *interpreter.Interpreter) exp
}
}
+func newExportableValues(inter *interpreter.Interpreter, values []interpreter.Value) []exportableValue {
+ exportableValues := make([]exportableValue, 0, len(values))
+
+ for _, value := range values {
+ exportableValues = append(exportableValues, newExportableValue(value, inter))
+ }
+
+ return exportableValues
+}
+
func (v exportableValue) Interpreter() *interpreter.Interpreter {
return v.inter
}
diff --git a/tools/constructorcheck/Makefile b/tools/constructorcheck/Makefile
index d81cf139a5..24c52ef2dc 100644
--- a/tools/constructorcheck/Makefile
+++ b/tools/constructorcheck/Makefile
@@ -1,3 +1,2 @@
-.PHONY: plugin
-plugin:
- go build -buildmode=plugin .
\ No newline at end of file
+constructorcheck.so: go.mod
+ go build -buildmode=plugin .
diff --git a/tools/constructorcheck/go.mod b/tools/constructorcheck/go.mod
index 16e6612fae..1a9332f039 100644
--- a/tools/constructorcheck/go.mod
+++ b/tools/constructorcheck/go.mod
@@ -1,10 +1,10 @@
module github.com/onflow/cadence/tools/constructorcheck
-go 1.18
+go 1.19
-require golang.org/x/tools v0.1.12
+require golang.org/x/tools v0.6.0
require (
- golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
- golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
+ golang.org/x/mod v0.8.0 // indirect
+ golang.org/x/sys v0.5.0 // indirect
)
diff --git a/tools/constructorcheck/go.sum b/tools/constructorcheck/go.sum
index 1c6a6614e7..44d387ef3f 100644
--- a/tools/constructorcheck/go.sum
+++ b/tools/constructorcheck/go.sum
@@ -1,6 +1,7 @@
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
-golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
-golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
+golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
diff --git a/tools/golangci-lint/Makefile b/tools/golangci-lint/Makefile
index ac711c6cb5..ddafc4d7a0 100644
--- a/tools/golangci-lint/Makefile
+++ b/tools/golangci-lint/Makefile
@@ -1,2 +1,2 @@
-golangci-lint:
+golangci-lint: go.mod
go build -o golangci-lint github.com/golangci/golangci-lint/cmd/golangci-lint
diff --git a/tools/golangci-lint/go.mod b/tools/golangci-lint/go.mod
index e7939fd723..07fa12d3f7 100644
--- a/tools/golangci-lint/go.mod
+++ b/tools/golangci-lint/go.mod
@@ -1,66 +1,68 @@
module github.com/filecoin-project/tools/golangci-lint
-go 1.18
+go 1.19
-require github.com/golangci/golangci-lint v1.49.0
+require github.com/golangci/golangci-lint v1.51.2
require (
- 4d63.com/gochecknoglobals v0.1.0 // indirect
+ 4d63.com/gocheckcompilerdirectives v1.2.1 // indirect
+ 4d63.com/gochecknoglobals v0.2.1 // indirect
+ github.com/Abirdcfly/dupword v0.0.9 // indirect
github.com/Antonboom/errname v0.1.7 // indirect
github.com/Antonboom/nilnil v0.1.1 // indirect
- github.com/BurntSushi/toml v1.2.0 // indirect
+ github.com/BurntSushi/toml v1.2.1 // indirect
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
- github.com/OpenPeeDeeP/depguard v1.1.0 // indirect
+ github.com/OpenPeeDeeP/depguard v1.1.1 // indirect
github.com/alexkohler/prealloc v1.0.0 // indirect
github.com/alingse/asasalint v0.0.11 // indirect
- github.com/ashanbrown/forbidigo v1.3.0 // indirect
+ github.com/ashanbrown/forbidigo v1.4.0 // indirect
github.com/ashanbrown/makezero v1.1.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bkielbasa/cyclop v1.2.0 // indirect
github.com/blizzy78/varnamelen v0.8.0 // indirect
- github.com/bombsimon/wsl/v3 v3.3.0 // indirect
+ github.com/bombsimon/wsl/v3 v3.4.0 // indirect
github.com/breml/bidichk v0.2.3 // indirect
github.com/breml/errchkjson v0.3.0 // indirect
github.com/butuzov/ireturn v0.1.1 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/charithe/durationcheck v0.0.9 // indirect
- github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 // indirect
- github.com/curioswitch/go-reassign v0.1.2 // indirect
- github.com/daixiang0/gci v0.6.3 // indirect
+ github.com/chavacava/garif v0.0.0-20221024190013-b3ef35877348 // indirect
+ github.com/curioswitch/go-reassign v0.2.0 // indirect
+ github.com/daixiang0/gci v0.9.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/denis-tingaikin/go-header v0.4.3 // indirect
github.com/esimonov/ifshort v1.0.4 // indirect
github.com/ettle/strcase v0.1.1 // indirect
- github.com/fatih/color v1.13.0 // indirect
+ github.com/fatih/color v1.14.1 // indirect
github.com/fatih/structtag v1.2.0 // indirect
github.com/firefart/nonamedreturns v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/fzipp/gocyclo v0.6.0 // indirect
- github.com/go-critic/go-critic v0.6.4 // indirect
- github.com/go-toolsmith/astcast v1.0.0 // indirect
- github.com/go-toolsmith/astcopy v1.0.1 // indirect
- github.com/go-toolsmith/astequal v1.0.2 // indirect
- github.com/go-toolsmith/astfmt v1.0.0 // indirect
- github.com/go-toolsmith/astp v1.0.0 // indirect
- github.com/go-toolsmith/strparse v1.0.0 // indirect
- github.com/go-toolsmith/typep v1.0.2 // indirect
- github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect
+ github.com/go-critic/go-critic v0.6.7 // indirect
+ github.com/go-toolsmith/astcast v1.1.0 // indirect
+ github.com/go-toolsmith/astcopy v1.0.3 // indirect
+ github.com/go-toolsmith/astequal v1.1.0 // indirect
+ github.com/go-toolsmith/astfmt v1.1.0 // indirect
+ github.com/go-toolsmith/astp v1.1.0 // indirect
+ github.com/go-toolsmith/strparse v1.1.0 // indirect
+ github.com/go-toolsmith/typep v1.1.0 // indirect
+ github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect
github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect
github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe // indirect
- github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a // indirect
+ github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 // indirect
github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 // indirect
github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca // indirect
- github.com/golangci/misspell v0.3.5 // indirect
+ github.com/golangci/misspell v0.4.0 // indirect
github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 // indirect
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect
- github.com/google/go-cmp v0.5.8 // indirect
- github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect
+ github.com/google/go-cmp v0.5.9 // indirect
+ github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28 // indirect
github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
github.com/gostaticanalysis/comment v1.4.2 // indirect
github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect
@@ -70,82 +72,85 @@ require (
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hexops/gotextdiff v1.0.3 // indirect
- github.com/inconshreveable/mousetrap v1.0.0 // indirect
+ github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/jgautheron/goconst v1.5.1 // indirect
github.com/jingyugao/rowserrcheck v1.1.1 // indirect
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect
github.com/julz/importas v0.1.0 // indirect
- github.com/kisielk/errcheck v1.6.2 // indirect
+ github.com/junk1tm/musttag v0.4.5 // indirect
+ github.com/kisielk/errcheck v1.6.3 // indirect
github.com/kisielk/gotool v1.0.0 // indirect
+ github.com/kkHAIKE/contextcheck v1.1.3 // indirect
github.com/kulti/thelper v0.6.3 // indirect
github.com/kunwardeep/paralleltest v1.0.6 // indirect
- github.com/kyoh86/exportloopref v0.1.8 // indirect
+ github.com/kyoh86/exportloopref v0.1.11 // indirect
github.com/ldez/gomoddirectives v0.2.3 // indirect
- github.com/ldez/tagliatelle v0.3.1 // indirect
- github.com/leonklingele/grouper v1.1.0 // indirect
+ github.com/ldez/tagliatelle v0.4.0 // indirect
+ github.com/leonklingele/grouper v1.1.1 // indirect
github.com/lufeee/execinquery v1.2.1 // indirect
github.com/magiconair/properties v1.8.6 // indirect
+ github.com/maratori/testableexamples v1.0.0 // indirect
github.com/maratori/testpackage v1.1.0 // indirect
github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
- github.com/mattn/go-isatty v0.0.16 // indirect
+ github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/mbilski/exhaustivestruct v1.2.0 // indirect
- github.com/mgechev/revive v1.2.3 // indirect
+ github.com/mgechev/revive v1.2.5 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/moricho/tparallel v0.2.1 // indirect
github.com/nakabonne/nestif v0.3.1 // indirect
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect
- github.com/nishanths/exhaustive v0.8.1 // indirect
+ github.com/nishanths/exhaustive v0.9.5 // indirect
github.com/nishanths/predeclared v0.2.2 // indirect
+ github.com/nunnatsa/ginkgolinter v0.8.1 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
- github.com/pelletier/go-toml/v2 v2.0.2 // indirect
- github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d // indirect
+ github.com/pelletier/go-toml/v2 v2.0.5 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
- github.com/polyfloyd/go-errorlint v1.0.2 // indirect
+ github.com/polyfloyd/go-errorlint v1.1.0 // indirect
github.com/prometheus/client_golang v1.12.1 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
- github.com/quasilyte/go-ruleguard v0.3.17 // indirect
- github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5 // indirect
+ github.com/quasilyte/go-ruleguard v0.3.19 // indirect
+ github.com/quasilyte/gogrep v0.5.0 // indirect
github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
- github.com/ryancurrah/gomodguard v1.2.4 // indirect
- github.com/ryanrolds/sqlclosecheck v0.3.0 // indirect
- github.com/sanposhiho/wastedassign/v2 v2.0.6 // indirect
+ github.com/ryancurrah/gomodguard v1.3.0 // indirect
+ github.com/ryanrolds/sqlclosecheck v0.4.0 // indirect
+ github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect
github.com/sashamelentyev/interfacebloat v1.1.0 // indirect
- github.com/sashamelentyev/usestdlibvars v1.13.0 // indirect
- github.com/securego/gosec/v2 v2.13.1 // indirect
+ github.com/sashamelentyev/usestdlibvars v1.23.0 // indirect
+ github.com/securego/gosec/v2 v2.15.0 // indirect
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/sivchari/containedctx v1.0.2 // indirect
github.com/sivchari/nosnakecase v1.7.0 // indirect
- github.com/sivchari/tenv v1.7.0 // indirect
+ github.com/sivchari/tenv v1.7.1 // indirect
github.com/sonatard/noctx v0.0.1 // indirect
- github.com/sourcegraph/go-diff v0.6.1 // indirect
+ github.com/sourcegraph/go-diff v0.7.0 // indirect
github.com/spf13/afero v1.8.2 // indirect
github.com/spf13/cast v1.5.0 // indirect
- github.com/spf13/cobra v1.5.0 // indirect
+ github.com/spf13/cobra v1.6.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.12.0 // indirect
github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect
- github.com/stretchr/objx v0.4.0 // indirect
- github.com/stretchr/testify v1.8.0 // indirect
- github.com/subosito/gotenv v1.4.0 // indirect
- github.com/sylvia7788/contextcheck v1.0.6 // indirect
+ github.com/stretchr/objx v0.5.0 // indirect
+ github.com/stretchr/testify v1.8.1 // indirect
+ github.com/subosito/gotenv v1.4.1 // indirect
+ github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect
github.com/tdakkota/asciicheck v0.1.1 // indirect
github.com/tetafro/godot v1.4.11 // indirect
- github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 // indirect
- github.com/timonwong/logrlint v0.1.0 // indirect
- github.com/tomarrell/wrapcheck/v2 v2.6.2 // indirect
- github.com/tommy-muehle/go-mnd/v2 v2.5.0 // indirect
+ github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e // indirect
+ github.com/timonwong/loggercheck v0.9.3 // indirect
+ github.com/tomarrell/wrapcheck/v2 v2.8.0 // indirect
+ github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect
github.com/ultraware/funlen v0.0.3 // indirect
github.com/ultraware/whitespace v0.0.5 // indirect
github.com/uudashr/gocognit v1.0.6 // indirect
@@ -156,19 +161,19 @@ require (
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.17.0 // indirect
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
- golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect
- golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
- golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
- golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
- golang.org/x/text v0.3.7 // indirect
- golang.org/x/tools v0.1.12 // indirect
+ golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9 // indirect
+ golang.org/x/mod v0.8.0 // indirect
+ golang.org/x/sync v0.1.0 // indirect
+ golang.org/x/sys v0.5.0 // indirect
+ golang.org/x/text v0.6.0 // indirect
+ golang.org/x/tools v0.6.0 // indirect
google.golang.org/protobuf v1.28.0 // indirect
- gopkg.in/ini.v1 v1.66.6 // indirect
+ gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
- honnef.co/go/tools v0.3.3 // indirect
- mvdan.cc/gofumpt v0.3.1 // indirect
+ honnef.co/go/tools v0.4.2 // indirect
+ mvdan.cc/gofumpt v0.4.0 // indirect
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect
- mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 // indirect
+ mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d // indirect
)
diff --git a/tools/golangci-lint/go.sum b/tools/golangci-lint/go.sum
index 9ec670339b..d721114bbb 100644
--- a/tools/golangci-lint/go.sum
+++ b/tools/golangci-lint/go.sum
@@ -1,5 +1,7 @@
-4d63.com/gochecknoglobals v0.1.0 h1:zeZSRqj5yCg28tCkIV/z/lWbwvNm5qnKVS15PI8nhD0=
-4d63.com/gochecknoglobals v0.1.0/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo=
+4d63.com/gocheckcompilerdirectives v1.2.1 h1:AHcMYuw56NPjq/2y615IGg2kYkBdTvOaojYCBcRE7MA=
+4d63.com/gocheckcompilerdirectives v1.2.1/go.mod h1:yjDJSxmDTtIHHCqX0ufRYZDL6vQtMG7tJdKVeWwsqvs=
+4d63.com/gochecknoglobals v0.2.1 h1:1eiorGsgHOFOuoOiJDy2psSrQbRdIHrlge0IJIkUgDc=
+4d63.com/gochecknoglobals v0.2.1/go.mod h1:KRE8wtJB3CXCsb1xy421JfTHIIbmT3U5ruxw2Qu8fSU=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
@@ -38,13 +40,15 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
+github.com/Abirdcfly/dupword v0.0.9 h1:MxprGjKq3yDBICXDgEEsyGirIXfMYXkLNT/agPsE1tk=
+github.com/Abirdcfly/dupword v0.0.9/go.mod h1:PzmHVLLZ27MvHSzV7eFmMXSFArWXZPZmfuuziuUrf2g=
github.com/Antonboom/errname v0.1.7 h1:mBBDKvEYwPl4WFFNwec1CZO096G6vzK9vvDQzAwkako=
github.com/Antonboom/errname v0.1.7/go.mod h1:g0ONh16msHIPgJSGsecu1G/dcF2hlYR/0SddnIAGavU=
github.com/Antonboom/nilnil v0.1.1 h1:PHhrh5ANKFWRBh7TdYmyyq2gyT2lotnvFvvFbylF81Q=
github.com/Antonboom/nilnil v0.1.1/go.mod h1:L1jBqoWM7AOeTD+tSquifKSesRHs4ZdaxvZR+xdJEaI=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0=
-github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
+github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
+github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM=
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
@@ -52,8 +56,8 @@ github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 h1:+r1rSv4gvYn0wmRjC8X7I
github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0/go.mod h1:b3g59n2Y+T5xmcxJL+UEG2f8cQploZm1mR/v6BW0mU0=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
-github.com/OpenPeeDeeP/depguard v1.1.0 h1:pjK9nLPS1FwQYGGpPxoMYpe7qACHOhAWQMQzV71i49o=
-github.com/OpenPeeDeeP/depguard v1.1.0/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc=
+github.com/OpenPeeDeeP/depguard v1.1.1 h1:TSUznLjvp/4IUP+OQ0t/4jF4QUyxIcVX8YnghZdunyA=
+github.com/OpenPeeDeeP/depguard v1.1.1/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
@@ -63,8 +67,8 @@ github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pO
github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE=
github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw=
github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I=
-github.com/ashanbrown/forbidigo v1.3.0 h1:VkYIwb/xxdireGAdJNZoo24O4lmnEWkactplBlWTShc=
-github.com/ashanbrown/forbidigo v1.3.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI=
+github.com/ashanbrown/forbidigo v1.4.0 h1:spdPbupaSqtWORq1Q4eHBoPBmHtwVyLKwaedbSLc5Sw=
+github.com/ashanbrown/forbidigo v1.4.0/go.mod h1:IvgwB5Y4fzqSAj/WVXKWigoTkB0dzI2FBbpKWuh7ph8=
github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s=
github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@@ -75,8 +79,8 @@ github.com/bkielbasa/cyclop v1.2.0 h1:7Jmnh0yL2DjKfw28p86YTd/B4lRGcNuu12sKE35sM7
github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI=
github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M=
github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k=
-github.com/bombsimon/wsl/v3 v3.3.0 h1:Mka/+kRLoQJq7g2rggtgQsjuI/K5Efd87WX96EWFxjM=
-github.com/bombsimon/wsl/v3 v3.3.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc=
+github.com/bombsimon/wsl/v3 v3.4.0 h1:RkSxjT3tmlptwfgEgTgU+KYKLI35p/tviNXNXiL2aNU=
+github.com/bombsimon/wsl/v3 v3.4.0/go.mod h1:KkIB+TXkqy6MvK9BDZVbZxKNYsE1/oLRJbIFtf14qqo=
github.com/breml/bidichk v0.2.3 h1:qe6ggxpTfA8E75hdjWPZ581sY3a2lnl0IRxLQFelECI=
github.com/breml/bidichk v0.2.3/go.mod h1:8u2C6DnAy0g2cEq+k/A2+tr9O1s+vHGxWn0LTc70T2A=
github.com/breml/errchkjson v0.3.0 h1:YdDqhfqMT+I1vIxPSas44P+9Z9HzJwCeAzjB8PxP1xw=
@@ -89,8 +93,8 @@ github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cb
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/charithe/durationcheck v0.0.9 h1:mPP4ucLrf/rKZiIG/a9IPXHGlh8p4CzgpyTy6EEutYk=
github.com/charithe/durationcheck v0.0.9/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg=
-github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 h1:E7LT642ysztPWE0dfz43cWOvMiF42DyTRC+eZIaO4yI=
-github.com/chavacava/garif v0.0.0-20220630083739-93517212f375/go.mod h1:4m1Rv7xfuwWPNKXlThldNuJvutYM6J95wNuuVmn55To=
+github.com/chavacava/garif v0.0.0-20221024190013-b3ef35877348 h1:cy5GCEZLUCshCGCRRUjxHrDUqkB4l5cuUt3ShEckQEo=
+github.com/chavacava/garif v0.0.0-20221024190013-b3ef35877348/go.mod h1:f/miWtG3SSuTxKsNK3o58H1xl+XV6ZIfbC6p7lPPB8U=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@@ -99,12 +103,10 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
-github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
-github.com/cristalhq/acmd v0.7.0/go.mod h1:LG5oa43pE/BbxtfMoImHCQN++0Su7dzipdgBjMCBVDQ=
-github.com/curioswitch/go-reassign v0.1.2 h1:ekM07+z+VFT560Exz4mTv0/s1yU9gem6CJc/tlYpkmI=
-github.com/curioswitch/go-reassign v0.1.2/go.mod h1:bFJIHgtTM3hRm2sKXSPkbwNjSFyGURQXyn4IXD2qwfQ=
-github.com/daixiang0/gci v0.6.3 h1:wUAqXChk8HbwXn8AfxD9DYSCp9Bpz1L3e6Q4Roe+q9E=
-github.com/daixiang0/gci v0.6.3/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c=
+github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo=
+github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc=
+github.com/daixiang0/gci v0.9.1 h1:jBrwBmBZTDsGsXiaCTLIe9diotp1X4X64zodFrh7l+c=
+github.com/daixiang0/gci v0.9.1/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -120,8 +122,8 @@ github.com/esimonov/ifshort v1.0.4 h1:6SID4yGWfRae/M7hkVDVVyppy8q/v9OuxNdmjLQStB
github.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0=
github.com/ettle/strcase v0.1.1 h1:htFueZyVeE1XNnMEfbqp5r67qAN/4r6ya1ysq8Q+Zcw=
github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY=
-github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
-github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
+github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
+github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y=
@@ -131,8 +133,8 @@ github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwV
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
-github.com/go-critic/go-critic v0.6.4 h1:tucuG1pvOyYgpBIrVxw0R6gwO42lNa92Aq3VaDoIs+E=
-github.com/go-critic/go-critic v0.6.4/go.mod h1:qL5SOlk7NtY6sJPoVCTKDIgzNOxHkkkOCVDyi9wJe1U=
+github.com/go-critic/go-critic v0.6.7 h1:1evPrElnLQ2LZtJfmNDzlieDhjnq36SLgNzisx06oPM=
+github.com/go-critic/go-critic v0.6.7/go.mod h1:fYZUijFdcnxgx6wPjQA2QEjIRaNCT0gO8bhexy6/QmE=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@@ -142,29 +144,28 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
-github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
-github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g=
-github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4=
-github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ=
-github.com/go-toolsmith/astcopy v1.0.1 h1:l09oBhAPyV74kLJ3ZO31iBU8htZGTwr9LTjuMCyL8go=
-github.com/go-toolsmith/astcopy v1.0.1/go.mod h1:4TcEdbElGc9twQEYpVo/aieIXfHhiuLh4aLAck6dO7Y=
-github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY=
-github.com/go-toolsmith/astequal v1.0.1/go.mod h1:4oGA3EZXTVItV/ipGiOx7NWkY5veFfcsOJVS2YxltLw=
-github.com/go-toolsmith/astequal v1.0.2 h1:+XvaV8zNxua+9+Oa4AHmgmpo4RYAbwr/qjNppLfX2yM=
+github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8=
+github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU=
+github.com/go-toolsmith/astcopy v1.0.3 h1:r0bgSRlMOAgO+BdQnVAcpMSMkrQCnV6ZJmIkrJgcJj0=
+github.com/go-toolsmith/astcopy v1.0.3/go.mod h1:4TcEdbElGc9twQEYpVo/aieIXfHhiuLh4aLAck6dO7Y=
github.com/go-toolsmith/astequal v1.0.2/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4=
-github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k=
-github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw=
-github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg=
-github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI=
+github.com/go-toolsmith/astequal v1.0.3/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4=
+github.com/go-toolsmith/astequal v1.1.0 h1:kHKm1AWqClYn15R0K1KKE4RG614D46n+nqUQ06E1dTw=
+github.com/go-toolsmith/astequal v1.1.0/go.mod h1:sedf7VIdCL22LD8qIvv7Nn9MuWJruQA/ysswh64lffQ=
+github.com/go-toolsmith/astfmt v1.1.0 h1:iJVPDPp6/7AaeLJEruMsBUlOYCmvg0MoCfJprsOmcco=
+github.com/go-toolsmith/astfmt v1.1.0/go.mod h1:OrcLlRwu0CuiIBp/8b5PYF9ktGVZUjlNMV634mhwuQ4=
+github.com/go-toolsmith/astp v1.1.0 h1:dXPuCl6u2llURjdPLLDxJeZInAeZ0/eZwFJmqZMnpQA=
+github.com/go-toolsmith/astp v1.1.0/go.mod h1:0T1xFGz9hicKs8Z5MfAqSUitoUYS30pDMsRVIDHs8CA=
github.com/go-toolsmith/pkgload v1.0.2-0.20220101231613-e814995d17c5 h1:eD9POs68PHkwrx7hAB78z1cb6PfGq/jyWn3wJywsH1o=
-github.com/go-toolsmith/pkgload v1.0.2-0.20220101231613-e814995d17c5/go.mod h1:3NAwwmD4uY/yggRxoEjk/S00MIV3A+H7rrE3i87eYxM=
-github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4=
github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8=
-github.com/go-toolsmith/typep v1.0.2 h1:8xdsa1+FSIH/RhEkgnD1j2CJOy5mNllW1Q9tRiYwvlk=
-github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU=
-github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo=
-github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
+github.com/go-toolsmith/strparse v1.1.0 h1:GAioeZUK9TGxnLS+qfdqNbA4z0SSm5zVNtCQiyP2Bvw=
+github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ=
+github.com/go-toolsmith/typep v1.1.0 h1:fIRYDyF+JywLfqzyhdiHzRop/GQDxxNhLGQ6gFUNHus=
+github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig=
+github.com/go-xmlfmt/xmlfmt v1.1.2 h1:Nea7b4icn8s57fTx1M5AI4qQT5HEM3rVUO8MuE6g80U=
+github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
@@ -204,16 +205,16 @@ github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9
github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk=
github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe h1:6RGUuS7EGotKx6J5HIP8ZtyMdiDscjMLfRBSPuzVVeo=
github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ=
-github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks=
-github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU=
-github.com/golangci/golangci-lint v1.49.0 h1:I8WHOavragDttlLHtSraHn/h39C+R60bEQ5NoGcHQr8=
-github.com/golangci/golangci-lint v1.49.0/go.mod h1:+V/7lLv449R6w9mQ3WdV0EKh7Je/jTylMeSwBZcLeWE=
+github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 h1:amWTbTGqOZ71ruzrdA+Nx5WA3tV1N0goTspwmKCQvBY=
+github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2/go.mod h1:9wOXstvyDRshQ9LggQuzBCGysxs3b6Uo/1MvYCR2NMs=
+github.com/golangci/golangci-lint v1.51.2 h1:yIcsT1X9ZYHdSpeWXRT1ORC/FPGSqDHbHsu9uk4FK7M=
+github.com/golangci/golangci-lint v1.51.2/go.mod h1:KH9Q7/3glwpYSknxUgUyLlAv46A8fsSKo1hH2wDvkr8=
github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA=
github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg=
github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA=
github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o=
-github.com/golangci/misspell v0.3.5 h1:pLzmVdl3VxTOncgzHcvLOKirdvcx/TydsClUQXTehjo=
-github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA=
+github.com/golangci/misspell v0.4.0 h1:KtVB/hTK4bbL/S6bs64rYyk8adjmh1BygbBiaAiX+a0=
+github.com/golangci/misspell v0.4.0/go.mod h1:W6O/bwV6lGDxUCChm2ykw9NQdd5bYd1Xkjo88UcWyJc=
github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 h1:DIPQnGy2Gv2FSA4B/hh8Q7xx3B7AIDk3DAMeHclH1vQ=
github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6/go.mod h1:0AKcRCkMoKvUvlf89F6O7H2LYdhr1zBh736mBItOdRs=
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys=
@@ -230,9 +231,9 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+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/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@@ -252,9 +253,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
-github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 h1:PVRE9d4AQKmbelZ7emNig1+NT27DUmKZn5qXxfio54U=
-github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0=
-github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
+github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28 h1:9alfqbrhuD+9fLZ4iaAVwhlp5PEhmnBt7yvK2Oy5C1U=
+github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0=
github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw=
github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk=
@@ -284,15 +284,14 @@ github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUq
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
-github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
-github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
+github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM=
github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4=
github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs=
github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c=
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48=
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0=
-github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@@ -304,10 +303,14 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY=
github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0=
-github.com/kisielk/errcheck v1.6.2 h1:uGQ9xI8/pgc9iOoCe7kWQgRE6SBTrCGmTSf0LrEtY7c=
-github.com/kisielk/errcheck v1.6.2/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw=
+github.com/junk1tm/musttag v0.4.5 h1:d+mpJ1vn6WFEVKHwkgJiIedis1u/EawKOuUTygAUtCo=
+github.com/junk1tm/musttag v0.4.5/go.mod h1:XkcL/9O6RmD88JBXb+I15nYRl9W4ExhgQeCBEhfMC8U=
+github.com/kisielk/errcheck v1.6.3 h1:dEKh+GLHcWm2oN34nMvDzn1sqI0i0WxPvrgiJA5JuM8=
+github.com/kisielk/errcheck v1.6.3/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw=
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/kkHAIKE/contextcheck v1.1.3 h1:l4pNvrb8JSwRd51ojtcOxOeHJzHek+MtOyXbaR0uvmw=
+github.com/kkHAIKE/contextcheck v1.1.3/go.mod h1:PG/cwd6c0705/LM0KTr1acO2gORUxkSVWyLJOFW5qoo=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
@@ -317,46 +320,43 @@ github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
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/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs=
github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I=
github.com/kunwardeep/paralleltest v1.0.6 h1:FCKYMF1OF2+RveWlABsdnmsvJrei5aoyZoaGS+Ugg8g=
github.com/kunwardeep/paralleltest v1.0.6/go.mod h1:Y0Y0XISdZM5IKm3TREQMZ6iteqn1YuwCsJO/0kL9Zes=
-github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M=
-github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg=
+github.com/kyoh86/exportloopref v0.1.11 h1:1Z0bcmTypkL3Q4k+IDHMWTcnCliEZcaPiIe0/ymEyhQ=
+github.com/kyoh86/exportloopref v0.1.11/go.mod h1:qkV4UF1zGl6EkF1ox8L5t9SwyeBAZ3qLMd6up458uqA=
github.com/ldez/gomoddirectives v0.2.3 h1:y7MBaisZVDYmKvt9/l1mjNCiSA1BVn34U0ObUcJwlhA=
github.com/ldez/gomoddirectives v0.2.3/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0=
-github.com/ldez/tagliatelle v0.3.1 h1:3BqVVlReVUZwafJUwQ+oxbx2BEX2vUG4Yu/NOfMiKiM=
-github.com/ldez/tagliatelle v0.3.1/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88=
-github.com/leonklingele/grouper v1.1.0 h1:tC2y/ygPbMFSBOs3DcyaEMKnnwH7eYKzohOtRrf0SAg=
-github.com/leonklingele/grouper v1.1.0/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY=
-github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/ldez/tagliatelle v0.4.0 h1:sylp7d9kh6AdXN2DpVGHBRb5guTVAgOxqNGhbqc4b1c=
+github.com/ldez/tagliatelle v0.4.0/go.mod h1:mNtTfrHy2haaBAw+VT7IBV6VXBThS7TCreYWbBcJ87I=
+github.com/leonklingele/grouper v1.1.1 h1:suWXRU57D4/Enn6pXR0QVqqWWrnJ9Osrz+5rjt8ivzU=
+github.com/leonklingele/grouper v1.1.1/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY=
github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM=
github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM=
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
+github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI=
+github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE=
github.com/maratori/testpackage v1.1.0 h1:GJY4wlzQhuBusMF1oahQCBtUV/AQ/k69IZ68vxaac2Q=
github.com/maratori/testpackage v1.1.0/go.mod h1:PeAhzU8qkCwdGEMTEupsHJNlQu2gZopMC6RjbhmHeDc=
github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7RXkts09K+dEBJWakUWwICVqYbA=
github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s=
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
-github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
-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.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
-github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo=
github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc=
-github.com/mgechev/revive v1.2.3 h1:NzIEEa9+WimQ6q2Ov7OcNeySS/IOcwtkQ8RAh0R5UJ4=
-github.com/mgechev/revive v1.2.3/go.mod h1:iAWlQishqCuj4yhV24FTnKSXGpbAA+0SckXB8GQMX/Q=
+github.com/mgechev/revive v1.2.5 h1:UF9AR8pOAuwNmhXj2odp4mxv9Nx2qUIwVz8ZsU+Mbec=
+github.com/mgechev/revive v1.2.5/go.mod h1:nFOXent79jMTISAfOAasKfy0Z2Ejq0WX7Qn/KAdYopI=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
@@ -375,15 +375,16 @@ github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4N
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA=
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
-github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
-github.com/nishanths/exhaustive v0.8.1 h1:0QKNascWv9qIHY7zRoZSxeRr6kuk5aAT3YXLTiDmjTo=
-github.com/nishanths/exhaustive v0.8.1/go.mod h1:qj+zJJUgJ76tR92+25+03oYUhzF4R7/2Wk7fGTfCHmg=
+github.com/nishanths/exhaustive v0.9.5 h1:TzssWan6orBiLYVqewCG8faud9qlFntJE30ACpzmGME=
+github.com/nishanths/exhaustive v0.9.5/go.mod h1:IbwrGdVMizvDcIxPYGVdQn5BqWJaOwpCvg4RGb8r/TA=
github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk=
github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c=
+github.com/nunnatsa/ginkgolinter v0.8.1 h1:/y4o/0hV+ruUHj4xXh89xlFjoaitnI4LnkpuYs02q1c=
+github.com/nunnatsa/ginkgolinter v0.8.1/go.mod h1:FYYLtszIdmzCH8XMaMPyxPVXZ7VCaIm55bA+gugx+14=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
-github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY=
-github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q=
+github.com/onsi/ginkgo/v2 v2.8.0 h1:pAM+oBNPrpXRs+E/8spkeGx9QgekbRVyr74EUvRVOUI=
+github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q=
github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k=
github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw=
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
@@ -392,10 +393,8 @@ github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT9
github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
-github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS+49Gw=
-github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI=
-github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA=
-github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw=
+github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg=
+github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -403,8 +402,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
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/polyfloyd/go-errorlint v1.0.2 h1:kp1yvHflYhTmw5m3MmBy8SCyQkKPjwDthVuMH0ug6Yk=
-github.com/polyfloyd/go-errorlint v1.0.2/go.mod h1:APVvOesVSAnne5SClsPxPdfvZTVDojXh1/G3qb5wjGI=
+github.com/polyfloyd/go-errorlint v1.1.0 h1:VKoEFg5yxSgJ2yFPVhxW7oGz+f8/OVcuMeNvcPIi6Eg=
+github.com/polyfloyd/go-errorlint v1.1.0/go.mod h1:Uss7Bc/izYG0leCMRx3WVlrpqWedSZk7V/FUQW6VJ6U=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
@@ -427,34 +426,29 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
-github.com/quasilyte/go-ruleguard v0.3.1-0.20210203134552-1b5a410e1cc8/go.mod h1:KsAh3x0e7Fkpgs+Q9pNLS5XpFSvYCEVl5gP9Pp1xp30=
-github.com/quasilyte/go-ruleguard v0.3.17 h1:cDdoaSbQg11LXPDQqiCK54QmQXsEQQCTIgdcpeULGSI=
-github.com/quasilyte/go-ruleguard v0.3.17/go.mod h1:sST5PvaR7yb/Az5ksX8oc88usJ4EGjmJv7cK7y3jyig=
-github.com/quasilyte/go-ruleguard/dsl v0.3.0/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
-github.com/quasilyte/go-ruleguard/dsl v0.3.21/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
-github.com/quasilyte/go-ruleguard/rules v0.0.0-20201231183845-9e62ed36efe1/go.mod h1:7JTjp89EGyU1d6XfBiXihJNG37wB2VRkd125Q1u7Plc=
-github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50=
-github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5 h1:PDWGei+Rf2bBiuZIbZmM20J2ftEy9IeUCHA8HbQqed8=
-github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5/go.mod h1:wSEyW6O61xRV6zb6My3HxrQ5/8ke7NE2OayqCHa3xRM=
+github.com/quasilyte/go-ruleguard v0.3.19 h1:tfMnabXle/HzOb5Xe9CUZYWXKfkS1KwRmZyPmD9nVcc=
+github.com/quasilyte/go-ruleguard v0.3.19/go.mod h1:lHSn69Scl48I7Gt9cX3VrbsZYvYiBYszZOZW4A+oTEw=
+github.com/quasilyte/gogrep v0.5.0 h1:eTKODPXbI8ffJMN+W2aE0+oL0z/nh8/5eNdiO34SOAo=
+github.com/quasilyte/gogrep v0.5.0/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng=
github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 h1:L8QM9bvf68pVdQ3bCFZMDmnt9yqcMBro1pC7F+IPYMY=
github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0=
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs=
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
+github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/ryancurrah/gomodguard v1.2.4 h1:CpMSDKan0LtNGGhPrvupAoLeObRFjND8/tU1rEOtBp4=
-github.com/ryancurrah/gomodguard v1.2.4/go.mod h1:+Kem4VjWwvFpUJRJSwa16s1tBJe+vbv02+naTow2f6M=
-github.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw=
-github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA=
-github.com/sanposhiho/wastedassign/v2 v2.0.6 h1:+6/hQIHKNJAUixEj6EmOngGIisyeI+T3335lYTyxRoA=
-github.com/sanposhiho/wastedassign/v2 v2.0.6/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI=
+github.com/ryancurrah/gomodguard v1.3.0 h1:q15RT/pd6UggBXVBuLps8BXRvl5GPBcwVA7BJHMLuTw=
+github.com/ryancurrah/gomodguard v1.3.0/go.mod h1:ggBxb3luypPEzqVtq33ee7YSN35V28XeGnid8dnni50=
+github.com/ryanrolds/sqlclosecheck v0.4.0 h1:i8SX60Rppc1wRuyQjMciLqIzV3xnoHB7/tXbr6RGYNI=
+github.com/ryanrolds/sqlclosecheck v0.4.0/go.mod h1:TBRRjzL31JONc9i4XMinicuo+s+E8yKZ5FN8X3G6CKQ=
+github.com/sanposhiho/wastedassign/v2 v2.0.7 h1:J+6nrY4VW+gC9xFzUc+XjPD3g3wF3je/NsJFwFK7Uxc=
+github.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI=
github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw=
github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ=
-github.com/sashamelentyev/usestdlibvars v1.13.0 h1:uObNudVEEHf6JbOJy5bgKJloA1bWjxR9fwgNFpPzKnI=
-github.com/sashamelentyev/usestdlibvars v1.13.0/go.mod h1:D2Wb7niIYmTB+gB8z7kh8tyP5ccof1dQ+SFk+WW5NtY=
-github.com/securego/gosec/v2 v2.13.1 h1:7mU32qn2dyC81MH9L2kefnQyRMUarfDER3iQyMHcjYM=
-github.com/securego/gosec/v2 v2.13.1/go.mod h1:EO1sImBMBWFjOTFzMWfTRrZW6M15gm60ljzrmy/wtHo=
+github.com/sashamelentyev/usestdlibvars v1.23.0 h1:01h+/2Kd+NblNItNeux0veSL5cBF1jbEOPrEhDzGYq0=
+github.com/sashamelentyev/usestdlibvars v1.23.0/go.mod h1:YPwr/Y1LATzHI93CqoPUN/2BzGQ/6N/cl/KwgR0B/aU=
+github.com/securego/gosec/v2 v2.15.0 h1:v4Ym7FF58/jlykYmmhZ7mTm7FQvN/setNm++0fgIAtw=
+github.com/securego/gosec/v2 v2.15.0/go.mod h1:VOjTrZOkUtSDt2QLSJmQBMWnvwiQPEjg0l+5juIqGk8=
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU=
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs=
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
@@ -468,18 +462,18 @@ github.com/sivchari/containedctx v1.0.2 h1:0hLQKpgC53OVF1VT7CeoFHk9YKstur1XOgfYI
github.com/sivchari/containedctx v1.0.2/go.mod h1:PwZOeqm4/DLoJOqMSIJs3aKqXRX4YO+uXww087KZ7Bw=
github.com/sivchari/nosnakecase v1.7.0 h1:7QkpWIRMe8x25gckkFd2A5Pi6Ymo0qgr4JrhGt95do8=
github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY=
-github.com/sivchari/tenv v1.7.0 h1:d4laZMBK6jpe5PWepxlV9S+LC0yXqvYHiq8E6ceoVVE=
-github.com/sivchari/tenv v1.7.0/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg=
+github.com/sivchari/tenv v1.7.1 h1:PSpuD4bu6fSmtWMxSGWcvqUUgIn7k3yOJhOIzVWn8Ak=
+github.com/sivchari/tenv v1.7.1/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg=
github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY=
github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI=
-github.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0HZqLQ=
-github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs=
+github.com/sourcegraph/go-diff v0.7.0 h1:9uLlrd5T46OXs5qpp8L/MTltk0zikUGi0sNNyCpA8G0=
+github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs=
github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo=
github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
-github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=
-github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
+github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
+github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
@@ -492,8 +486,9 @@ github.com/stbenjam/no-sprintf-host-port v0.1.1 h1:tYugd/yrm1O0dV+ThCbaKZh195Dfm
github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8LHsN9N74I+PhRquPsxpL0I=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
@@ -501,13 +496,13 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
-github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs=
-github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo=
-github.com/sylvia7788/contextcheck v1.0.6 h1:o2EZgVPyMKE/Mtoqym61DInKEjwEbsmyoxg3VrmjNO4=
-github.com/sylvia7788/contextcheck v1.0.6/go.mod h1:9XDxwvxyuKD+8N+a7Gs7bfWLityh5t70g/GjdEt2N2M=
+github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=
+github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
+github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c h1:+aPplBwWcHBo6q9xrfWdMrT9o4kltkmmvpemgIjep/8=
+github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c/go.mod h1:SbErYREK7xXdsRiigaQiQkI9McGRzYMvlKYaP3Nimdk=
github.com/tdakkota/asciicheck v0.1.1 h1:PKzG7JUTUmVspQTDqtkX9eSiLGossXTybutHwTXuO0A=
github.com/tdakkota/asciicheck v0.1.1/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM=
github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA=
@@ -516,14 +511,14 @@ github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpR
github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY=
github.com/tetafro/godot v1.4.11 h1:BVoBIqAf/2QdbFmSwAWnaIqDivZdOV0ZRwEm6jivLKw=
github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8=
-github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 h1:kl4KhGNsJIbDHS9/4U9yQo1UcPQM0kOMJHn29EoH/Ro=
-github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
-github.com/timonwong/logrlint v0.1.0 h1:phZCcypL/vtx6cGxObJgWZ5wexZF5SXFPLOM+ru0e/M=
-github.com/timonwong/logrlint v0.1.0/go.mod h1:Zleg4Gw+kRxNej+Ra7o+tEaW5k1qthTaYKU7rSD39LU=
-github.com/tomarrell/wrapcheck/v2 v2.6.2 h1:3dI6YNcrJTQ/CJQ6M/DUkc0gnqYSIk6o0rChn9E/D0M=
-github.com/tomarrell/wrapcheck/v2 v2.6.2/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg=
-github.com/tommy-muehle/go-mnd/v2 v2.5.0 h1:iAj0a8e6+dXSL7Liq0aXPox36FiN1dBbjA6lt9fl65s=
-github.com/tommy-muehle/go-mnd/v2 v2.5.0/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw=
+github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e h1:MV6KaVu/hzByHP0UvJ4HcMGE/8a6A4Rggc/0wx2AvJo=
+github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e/go.mod h1:27bSVNWSBOHm+qRp1T9qzaIpsWEP6TbUnei/43HK+PQ=
+github.com/timonwong/loggercheck v0.9.3 h1:ecACo9fNiHxX4/Bc02rW2+kaJIAMAes7qJ7JKxt0EZI=
+github.com/timonwong/loggercheck v0.9.3/go.mod h1:wUqnk9yAOIKtGA39l1KLE9Iz0QiTocu/YZoOf+OzFdw=
+github.com/tomarrell/wrapcheck/v2 v2.8.0 h1:qDzbir0xmoE+aNxGCPrn+rUSxAX+nG6vREgbbXAR81I=
+github.com/tomarrell/wrapcheck/v2 v2.8.0/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg=
+github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw=
+github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw=
github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA=
github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
github.com/ultraware/whitespace v0.0.5 h1:hh+/cpIcopyMYbZNVov9iSxvJU3OYQg78Sfaqzi/CzI=
@@ -564,6 +559,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -577,8 +573,8 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
-golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d h1:+W8Qf4iJtMGKkyAygcKohjxTk4JPsL9DpzApJ22m5Ic=
-golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
+golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9 h1:6WHiuFL9FNjg8RljAaT7FNUuKDbvMqS1i5cr2OE2sLQ=
+golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -605,8 +601,11 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
+golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -643,8 +642,12 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
+golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
+golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
+golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
+golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -666,8 +669,9 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -685,7 +689,6 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -714,7 +717,6 @@ golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -723,10 +725,19 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
+golang.org/x/sys v0.5.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-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
+golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
+golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -734,8 +745,11 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
+golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -749,7 +763,6 @@ golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
@@ -759,7 +772,6 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20190916130336-e45ffcd953cc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -788,24 +800,19 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
-golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20201230224404-63754364767c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
@@ -813,12 +820,16 @@ golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0t
golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.9-0.20211228192929-ee1ca4ffc4da/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
-golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
+golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
+golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
+golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k=
+golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -920,10 +931,9 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
-gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
-gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI=
-gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
+gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -943,16 +953,16 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-honnef.co/go/tools v0.3.3 h1:oDx7VAwstgpYpb3wv0oxiZlxY+foCpRAwY7Vk6XpAgA=
-honnef.co/go/tools v0.3.3/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw=
-mvdan.cc/gofumpt v0.3.1 h1:avhhrOmv0IuvQVK7fvwV91oFSGAk5/6Po8GXTzICeu8=
-mvdan.cc/gofumpt v0.3.1/go.mod h1:w3ymliuxvzVx8DAutBnVyDqYb1Niy/yCJt/lk821YCE=
+honnef.co/go/tools v0.4.2 h1:6qXr+R5w+ktL5UkwEbPp+fEvfyoMPche6GkOpGHZcLc=
+honnef.co/go/tools v0.4.2/go.mod h1:36ZgoUOrqOk1GxwHhyryEkq8FQWkUO2xGuSMhUCcdvA=
+mvdan.cc/gofumpt v0.4.0 h1:JVf4NN1mIpHogBj7ABpgOyZc65/UUOkKQFkoURsz4MM=
+mvdan.cc/gofumpt v0.4.0/go.mod h1:PljLOHDeZqgS8opHRKLzp2It2VBuSdteAgqUfzMTxlQ=
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I=
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo=
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
-mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 h1:seuXWbRB1qPrS3NQnHmFKLJLtskWyueeIzmLXghMGgk=
-mvdan.cc/unparam v0.0.0-20220706161116-678bad134442/go.mod h1:F/Cxw/6mVrNKqrR2YjFf5CaW0Bw4RL8RfbEf4GRggJk=
+mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d h1:3rvTIIM22r9pvXk+q3swxUQAQOxksVMGK7sml4nG57w=
+mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d/go.mod h1:IeHQjmn6TOD+e4Z3RFiZMMsLVL+A96Nvptar8Fj71is=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
diff --git a/tools/maprange/Makefile b/tools/maprange/Makefile
index d81cf139a5..5485d4a205 100644
--- a/tools/maprange/Makefile
+++ b/tools/maprange/Makefile
@@ -1,3 +1,2 @@
-.PHONY: plugin
-plugin:
- go build -buildmode=plugin .
\ No newline at end of file
+maprange.so: go.mod
+ go build -buildmode=plugin .
diff --git a/tools/maprange/go.mod b/tools/maprange/go.mod
index fbf8b24b1b..f606575814 100644
--- a/tools/maprange/go.mod
+++ b/tools/maprange/go.mod
@@ -1,10 +1,10 @@
module github.com/onflow/cadence/tools/maprange
-go 1.18
+go 1.19
-require golang.org/x/tools v0.1.12
+require golang.org/x/tools v0.6.0
require (
- golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
- golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
+ golang.org/x/mod v0.8.0 // indirect
+ golang.org/x/sys v0.5.0 // indirect
)
diff --git a/tools/maprange/go.sum b/tools/maprange/go.sum
index 1c6a6614e7..44d387ef3f 100644
--- a/tools/maprange/go.sum
+++ b/tools/maprange/go.sum
@@ -1,6 +1,7 @@
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
-golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
-golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
+golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
diff --git a/tools/unkeyed/Makefile b/tools/unkeyed/Makefile
index d81cf139a5..240422e9be 100644
--- a/tools/unkeyed/Makefile
+++ b/tools/unkeyed/Makefile
@@ -1,3 +1,2 @@
-.PHONY: plugin
-plugin:
- go build -buildmode=plugin .
\ No newline at end of file
+unkeyed.so: go.mod
+ go build -buildmode=plugin .
diff --git a/tools/unkeyed/go.mod b/tools/unkeyed/go.mod
index 499eff1e1b..b002306faf 100644
--- a/tools/unkeyed/go.mod
+++ b/tools/unkeyed/go.mod
@@ -1,13 +1,13 @@
module github.com/onflow/cadence/tools/unkeyed
-go 1.18
+go 1.19
require (
- golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d
- golang.org/x/tools v0.1.12
+ golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9
+ golang.org/x/tools v0.6.0
)
require (
- golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
- golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
+ golang.org/x/mod v0.8.0 // indirect
+ golang.org/x/sys v0.5.0 // indirect
)
diff --git a/tools/unkeyed/go.sum b/tools/unkeyed/go.sum
index a72f2cebde..381b6c01cf 100644
--- a/tools/unkeyed/go.sum
+++ b/tools/unkeyed/go.sum
@@ -1,8 +1,9 @@
-golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d h1:+W8Qf4iJtMGKkyAygcKohjxTk4JPsL9DpzApJ22m5Ic=
-golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
-golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
-golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9 h1:6WHiuFL9FNjg8RljAaT7FNUuKDbvMqS1i5cr2OE2sLQ=
+golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
+golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
+golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
diff --git a/types.go b/types.go
index 43f2d4c705..70b08781f3 100644
--- a/types.go
+++ b/types.go
@@ -1092,12 +1092,12 @@ func NewStructType(
func NewMeteredStructType(
gauge common.MemoryGauge,
location common.Location,
- qualifiedIdentifer string,
+ qualifiedIdentifier string,
fields []Field,
initializers [][]Parameter,
) *StructType {
common.UseMemory(gauge, common.CadenceStructTypeMemoryUsage)
- return NewStructType(location, qualifiedIdentifer, fields, initializers)
+ return NewStructType(location, qualifiedIdentifier, fields, initializers)
}
func (*StructType) isType() {}
@@ -1153,13 +1153,13 @@ type ResourceType struct {
func NewResourceType(
location common.Location,
- qualifiedIdentifer string,
+ qualifiedIdentifier string,
fields []Field,
initializers [][]Parameter,
) *ResourceType {
return &ResourceType{
Location: location,
- QualifiedIdentifier: qualifiedIdentifer,
+ QualifiedIdentifier: qualifiedIdentifier,
Fields: fields,
Initializers: initializers,
}
@@ -1168,12 +1168,12 @@ func NewResourceType(
func NewMeteredResourceType(
gauge common.MemoryGauge,
location common.Location,
- qualifiedIdentifer string,
+ qualifiedIdentifier string,
fields []Field,
initializers [][]Parameter,
) *ResourceType {
common.UseMemory(gauge, common.CadenceResourceTypeMemoryUsage)
- return NewResourceType(location, qualifiedIdentifer, fields, initializers)
+ return NewResourceType(location, qualifiedIdentifier, fields, initializers)
}
func (*ResourceType) isType() {}
@@ -1312,13 +1312,13 @@ type EventType struct {
func NewEventType(
location common.Location,
- qualifiedIdentifer string,
+ qualifiedIdentifier string,
fields []Field,
initializer []Parameter,
) *EventType {
return &EventType{
Location: location,
- QualifiedIdentifier: qualifiedIdentifer,
+ QualifiedIdentifier: qualifiedIdentifier,
Fields: fields,
Initializer: initializer,
}
@@ -1327,12 +1327,12 @@ func NewEventType(
func NewMeteredEventType(
gauge common.MemoryGauge,
location common.Location,
- qualifiedIdentifer string,
+ qualifiedIdentifier string,
fields []Field,
initializer []Parameter,
) *EventType {
common.UseMemory(gauge, common.CadenceEventTypeMemoryUsage)
- return NewEventType(location, qualifiedIdentifer, fields, initializer)
+ return NewEventType(location, qualifiedIdentifier, fields, initializer)
}
func (*EventType) isType() {}
diff --git a/values.go b/values.go
index f944024f0e..df7f603e35 100644
--- a/values.go
+++ b/values.go
@@ -1426,7 +1426,7 @@ func (v Array) String() string {
// Dictionary
type Dictionary struct {
- DictionaryType Type
+ DictionaryType *DictionaryType
Pairs []KeyValuePair
}
@@ -1453,6 +1453,11 @@ func NewMeteredDictionary(
func (Dictionary) isValue() {}
func (v Dictionary) Type() Type {
+ if v.DictionaryType == nil {
+ // Return nil Type instead of Type referencing nil *DictionaryType,
+ // so caller can check if v's type is nil and also prevent nil pointer dereference.
+ return nil
+ }
return v.DictionaryType
}
@@ -1541,6 +1546,11 @@ func NewMeteredStruct(
func (Struct) isValue() {}
func (v Struct) Type() Type {
+ if v.StructType == nil {
+ // Return nil Type instead of Type referencing nil *StructType,
+ // so caller can check if v's type is nil and also prevent nil pointer dereference.
+ return nil
+ }
return v.StructType
}
@@ -1619,6 +1629,11 @@ func NewMeteredResource(
func (Resource) isValue() {}
func (v Resource) Type() Type {
+ if v.ResourceType == nil {
+ // Return nil Type instead of Type referencing nil *ResourceType,
+ // so caller can check if v's type is nil and also prevent nil pointer dereference.
+ return nil
+ }
return v.ResourceType
}
@@ -1676,6 +1691,11 @@ func NewMeteredAttachment(
func (Attachment) isValue() {}
func (v Attachment) Type() Type {
+ if v.AttachmentType == nil {
+ // Return nil Type instead of Type referencing nil *AttachmentType,
+ // so caller can check if v's type is nil and also prevent nil pointer dereference.
+ return nil
+ }
return v.AttachmentType
}
@@ -1733,6 +1753,11 @@ func NewMeteredEvent(
func (Event) isValue() {}
func (v Event) Type() Type {
+ if v.EventType == nil {
+ // Return nil Type instead of Type referencing nil *EventType,
+ // so caller can check if v's type is nil and also prevent nil pointer dereference.
+ return nil
+ }
return v.EventType
}
@@ -1789,6 +1814,11 @@ func NewMeteredContract(
func (Contract) isValue() {}
func (v Contract) Type() Type {
+ if v.ContractType == nil {
+ // Return nil Type instead of Type referencing nil *ContractType,
+ // so caller can check if v's type is nil and also prevent nil pointer dereference.
+ return nil
+ }
return v.ContractType
}
@@ -1815,6 +1845,49 @@ func (v Contract) String() string {
return formatComposite(v.ContractType.ID(), v.ContractType.Fields, v.Fields)
}
+// PathLink
+
+type PathLink struct {
+ TargetPath Path
+ // TODO: a future version might want to export the whole type
+ BorrowType string
+}
+
+var _ Value = PathLink{}
+
+func NewPathLink(targetPath Path, borrowType string) PathLink {
+ return PathLink{
+ TargetPath: targetPath,
+ BorrowType: borrowType,
+ }
+}
+
+func NewMeteredLink(gauge common.MemoryGauge, targetPath Path, borrowType string) PathLink {
+ common.UseMemory(gauge, common.CadencePathLinkValueMemoryUsage)
+ return NewPathLink(targetPath, borrowType)
+}
+
+func (PathLink) isValue() {}
+
+func (v PathLink) Type() Type {
+ return nil
+}
+
+func (v PathLink) MeteredType(_ common.MemoryGauge) Type {
+ return v.Type()
+}
+
+func (v PathLink) ToGoValue() any {
+ return nil
+}
+
+func (v PathLink) String() string {
+ return format.PathLink(
+ v.BorrowType,
+ v.TargetPath.String(),
+ )
+}
+
// Path
type Path struct {
@@ -1969,6 +2042,11 @@ func NewMeteredEnum(
func (Enum) isValue() {}
func (v Enum) Type() Type {
+ if v.EnumType == nil {
+ // Return nil Type instead of Type referencing nil *EnumType,
+ // so caller can check if v's type is nil and also prevent nil pointer dereference.
+ return nil
+ }
return v.EnumType
}
@@ -2016,6 +2094,11 @@ func NewMeteredFunction(gauge common.MemoryGauge, functionType *FunctionType) Fu
func (Function) isValue() {}
func (v Function) Type() Type {
+ if v.FunctionType == nil {
+ // Return nil Type instead of Type referencing nil *FunctionType,
+ // so caller can check if v's type is nil and also prevent nil pointer dereference.
+ return nil
+ }
return v.FunctionType
}
diff --git a/values_test.go b/values_test.go
index 695f3d42e7..85080e7eb7 100644
--- a/values_test.go
+++ b/values_test.go
@@ -21,10 +21,8 @@ package cadence
import (
"fmt"
"math/big"
- "reflect"
"testing"
"unicode/utf8"
- "unsafe"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -33,129 +31,171 @@ import (
"github.com/onflow/cadence/runtime/tests/utils"
)
-func TestStringer(t *testing.T) {
-
- t.Parallel()
-
- type testCase struct {
- value Value
- expected string
- }
+type valueTestCase struct {
+ value Value
+ string string
+ exampleType Type
+ expectedType Type
+ withType func(value Value, ty Type) Value
+ noType bool
+}
+func newValueTestCases() map[string]valueTestCase {
ufix64, _ := NewUFix64("64.01")
fix64, _ := NewFix64("-32.11")
- stringerTests := map[string]testCase{
+ testFunctionType := NewFunctionType(
+ "((String):UInt8)",
+ FunctionPurityUnspecified,
+ []Parameter{
+ {
+ Type: StringType{},
+ },
+ },
+ UInt8Type{},
+ )
+
+ return map[string]valueTestCase{
"UInt": {
- value: NewUInt(10),
- expected: "10",
+ value: NewUInt(10),
+ string: "10",
+ expectedType: UIntType{},
},
"UInt8": {
- value: NewUInt8(8),
- expected: "8",
+ value: NewUInt8(8),
+ string: "8",
+ expectedType: UInt8Type{},
},
"UInt16": {
- value: NewUInt16(16),
- expected: "16",
+ value: NewUInt16(16),
+ string: "16",
+ expectedType: UInt16Type{},
},
"UInt32": {
- value: NewUInt32(32),
- expected: "32",
+ value: NewUInt32(32),
+ string: "32",
+ expectedType: UInt32Type{},
},
"UInt64": {
- value: NewUInt64(64),
- expected: "64",
+ value: NewUInt64(64),
+ string: "64",
+ expectedType: UInt64Type{},
},
"UInt128": {
- value: NewUInt128(128),
- expected: "128",
+ value: NewUInt128(128),
+ string: "128",
+ expectedType: UInt128Type{},
},
"UInt256": {
- value: NewUInt256(256),
- expected: "256",
+ value: NewUInt256(256),
+ string: "256",
+ expectedType: UInt256Type{},
},
"Int": {
- value: NewInt(1000000),
- expected: "1000000",
+ value: NewInt(1000000),
+ string: "1000000",
+ expectedType: IntType{},
},
"Int8": {
- value: NewInt8(-8),
- expected: "-8",
+ value: NewInt8(-8),
+ string: "-8",
+ expectedType: Int8Type{},
},
"Int16": {
- value: NewInt16(-16),
- expected: "-16",
+ value: NewInt16(-16),
+ string: "-16",
+ expectedType: Int16Type{},
},
"Int32": {
- value: NewInt32(-32),
- expected: "-32",
+ value: NewInt32(-32),
+ string: "-32",
+ expectedType: Int32Type{},
},
"Int64": {
- value: NewInt64(-64),
- expected: "-64",
+ value: NewInt64(-64),
+ string: "-64",
+ expectedType: Int64Type{},
},
"Int128": {
- value: NewInt128(-128),
- expected: "-128",
+ value: NewInt128(-128),
+ string: "-128",
+ expectedType: Int128Type{},
},
"Int256": {
- value: NewInt256(-256),
- expected: "-256",
+ value: NewInt256(-256),
+ string: "-256",
+ expectedType: Int256Type{},
},
"Word8": {
- value: NewWord8(8),
- expected: "8",
+ value: NewWord8(8),
+ string: "8",
+ expectedType: Word8Type{},
},
"Word16": {
- value: NewWord16(16),
- expected: "16",
+ value: NewWord16(16),
+ string: "16",
+ expectedType: Word16Type{},
},
"Word32": {
- value: NewWord32(32),
- expected: "32",
+ value: NewWord32(32),
+ string: "32",
+ expectedType: Word32Type{},
},
"Word64": {
- value: NewWord64(64),
- expected: "64",
+ value: NewWord64(64),
+ string: "64",
+ expectedType: Word64Type{},
},
"UFix64": {
- value: ufix64,
- expected: "64.01000000",
+ value: ufix64,
+ string: "64.01000000",
+ expectedType: UFix64Type{},
},
"Fix64": {
- value: fix64,
- expected: "-32.11000000",
+ value: fix64,
+ string: "-32.11000000",
+ expectedType: Fix64Type{},
},
"Void": {
- value: NewVoid(),
- expected: "()",
+ value: NewVoid(),
+ string: "()",
+ expectedType: VoidType{},
},
- "true": {
- value: NewBool(true),
- expected: "true",
- },
- "false": {
- value: NewBool(false),
- expected: "false",
+ "Bool": {
+ value: NewBool(true),
+ string: "true",
+ expectedType: BoolType{},
},
"some": {
- value: NewOptional(ufix64),
- expected: "64.01000000",
+ value: NewOptional(ufix64),
+ string: "64.01000000",
+ expectedType: NewOptionalType(UFix64Type{}),
},
"nil": {
- value: NewOptional(nil),
- expected: "nil",
+ value: NewOptional(nil),
+ string: "nil",
+ expectedType: NewOptionalType(NeverType{}),
},
"String": {
- value: String("Flow ridah!"),
- expected: "\"Flow ridah!\"",
+ value: String("Flow ridah!"),
+ string: "\"Flow ridah!\"",
+ expectedType: StringType{},
+ },
+ "Character": {
+ value: Character("✌️"),
+ string: "\"\\u{270c}\\u{fe0f}\"",
+ expectedType: CharacterType{},
},
"Array": {
value: NewArray([]Value{
NewInt(10),
String("TEST"),
}),
- expected: "[10, \"TEST\"]",
+ exampleType: NewConstantSizedArrayType(2, AnyType{}),
+ withType: func(value Value, ty Type) Value {
+ return value.(Array).WithType(ty.(ArrayType))
+ },
+ string: "[10, \"TEST\"]",
},
"Dictionary": {
value: NewDictionary([]KeyValuePair{
@@ -164,18 +204,25 @@ func TestStringer(t *testing.T) {
Value: String("value"),
},
}),
- expected: "{\"key\": \"value\"}",
+ exampleType: NewDictionaryType(StringType{}, StringType{}),
+ withType: func(value Value, ty Type) Value {
+ return value.(Dictionary).WithType(ty.(*DictionaryType))
+ },
+ string: "{\"key\": \"value\"}",
},
"Bytes": {
- value: NewBytes([]byte{0x1, 0x2}),
- expected: "[0x1, 0x2]",
+ value: NewBytes([]byte{0x1, 0x2}),
+ string: "[0x1, 0x2]",
+ expectedType: BytesType{},
},
"Address": {
- value: NewAddress([8]byte{0, 0, 0, 0, 0, 0, 0, 1}),
- expected: "0x0000000000000001",
+ value: NewAddress([8]byte{0, 0, 0, 0, 0, 0, 0, 1}),
+ string: "0x0000000000000001",
+ expectedType: AddressType{},
},
"struct": {
- value: NewStruct([]Value{String("bar")}).WithType(&StructType{
+ value: NewStruct([]Value{String("bar")}),
+ exampleType: &StructType{
Location: utils.TestLocation,
QualifiedIdentifier: "FooStruct",
Fields: []Field{
@@ -184,11 +231,15 @@ func TestStringer(t *testing.T) {
Type: StringType{},
},
},
- }),
- expected: "S.test.FooStruct(y: \"bar\")",
+ },
+ withType: func(value Value, ty Type) Value {
+ return value.(Struct).WithType(ty.(*StructType))
+ },
+ string: "S.test.FooStruct(y: \"bar\")",
},
"resource": {
- value: NewResource([]Value{NewInt(1)}).WithType(&ResourceType{
+ value: NewResource([]Value{NewInt(1)}),
+ exampleType: &ResourceType{
Location: utils.TestLocation,
QualifiedIdentifier: "FooResource",
Fields: []Field{
@@ -197,8 +248,11 @@ func TestStringer(t *testing.T) {
Type: IntType{},
},
},
- }),
- expected: "S.test.FooResource(bar: 1)",
+ },
+ withType: func(value Value, ty Type) Value {
+ return value.(Resource).WithType(ty.(*ResourceType))
+ },
+ string: "S.test.FooResource(bar: 1)",
},
"event": {
value: NewEvent(
@@ -206,7 +260,8 @@ func TestStringer(t *testing.T) {
NewInt(1),
String("foo"),
},
- ).WithType(&EventType{
+ ),
+ exampleType: &EventType{
Location: utils.TestLocation,
QualifiedIdentifier: "FooEvent",
Fields: []Field{
@@ -219,11 +274,15 @@ func TestStringer(t *testing.T) {
Type: StringType{},
},
},
- }),
- expected: "S.test.FooEvent(a: 1, b: \"foo\")",
+ },
+ withType: func(value Value, ty Type) Value {
+ return value.(Event).WithType(ty.(*EventType))
+ },
+ string: "S.test.FooEvent(a: 1, b: \"foo\")",
},
"contract": {
- value: NewContract([]Value{String("bar")}).WithType(&ContractType{
+ value: NewContract([]Value{String("bar")}),
+ exampleType: &ContractType{
Location: utils.TestLocation,
QualifiedIdentifier: "FooContract",
Fields: []Field{
@@ -232,19 +291,69 @@ func TestStringer(t *testing.T) {
Type: StringType{},
},
},
- }),
- expected: "S.test.FooContract(y: \"bar\")",
+ },
+ withType: func(value Value, ty Type) Value {
+ return value.(Contract).WithType(ty.(*ContractType))
+ },
+ string: "S.test.FooContract(y: \"bar\")",
+ },
+ "enum": {
+ value: NewEnum([]Value{UInt8(1)}),
+ exampleType: &EnumType{
+ Location: utils.TestLocation,
+ QualifiedIdentifier: "FooEnum",
+ Fields: []Field{
+ {
+ Identifier: sema.EnumRawValueFieldName,
+ Type: UInt8Type{},
+ },
+ },
+ },
+ withType: func(value Value, ty Type) Value {
+ return value.(Enum).WithType(ty.(*EnumType))
+ },
+ string: "S.test.FooEnum(rawValue: 1)",
+ },
+ "attachment": {
+ value: NewAttachment([]Value{NewInt(1)}),
+ exampleType: &AttachmentType{
+ Location: utils.TestLocation,
+ QualifiedIdentifier: "FooAttachment",
+ Fields: []Field{
+ {
+ Identifier: "bar",
+ Type: IntType{},
+ },
+ },
+ },
+ withType: func(value Value, ty Type) Value {
+ return value.(Attachment).WithType(ty.(*AttachmentType))
+ },
+ string: "S.test.FooAttachment(bar: 1)",
+ },
+ "Link": {
+ value: NewPathLink(
+ Path{
+ Domain: "storage",
+ Identifier: "foo",
+ },
+ "Int",
+ ),
+ string: "PathLink(/storage/foo)",
+ noType: true,
},
"Path": {
value: Path{
Domain: "storage",
Identifier: "foo",
},
- expected: "/storage/foo",
+ expectedType: PathType{},
+ string: "/storage/foo",
},
"Type": {
- value: TypeValue{StaticType: IntType{}},
- expected: "Type()",
+ value: TypeValue{StaticType: IntType{}},
+ expectedType: NewMetaType(),
+ string: "Type()",
},
"Capability": {
value: StorageCapability{
@@ -252,29 +361,47 @@ func TestStringer(t *testing.T) {
Address: BytesToAddress([]byte{1, 2, 3, 4, 5}),
BorrowType: IntType{},
},
- expected: "Capability(address: 0x0000000102030405, path: /storage/foo)",
+ expectedType: NewCapabilityType(IntType{}),
+ string: "Capability(address: 0x0000000102030405, path: /storage/foo)",
+ },
+ "Function": {
+ value: NewFunction(
+ testFunctionType,
+ ),
+ expectedType: testFunctionType,
+ string: "Function(...)",
},
}
+}
+
+func TestValue_String(t *testing.T) {
- test := func(name string, testCase testCase) {
+ t.Parallel()
+
+ test := func(name string, testCase valueTestCase) {
t.Run(name, func(t *testing.T) {
t.Parallel()
+ withType := testCase.withType
+ if withType != nil {
+ testCase.value = withType(testCase.value, testCase.exampleType)
+ }
+
assert.Equal(t,
- testCase.expected,
+ testCase.string,
testCase.value.String(),
)
})
}
- for name, testCase := range stringerTests {
+ for name, testCase := range newValueTestCases() {
test(name, testCase)
}
}
-func TestToBigEndianBytes(t *testing.T) {
+func TestNumberValue_ToBigEndianBytes(t *testing.T) {
t.Parallel()
@@ -622,112 +749,50 @@ func TestNewUInt256FromBig(t *testing.T) {
require.Error(t, err)
}
-//go:linkname typelinks reflect.typelinks
-func typelinks() (sections []unsafe.Pointer, offset [][]int32)
-
-//go:linkname add reflect.add
-func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer
-
-func TestGetType(t *testing.T) {
+func TestValue_Type(t *testing.T) {
t.Parallel()
- t.Run("simple values", func(t *testing.T) {
-
- // This method test all simple typed values (and any newly added values/types).
-
- t.Parallel()
+ checkedTypes := map[Type]struct{}{}
- complexTypes := map[reflect.Type]struct{}{
- reflect.TypeOf(Array{}): {},
- reflect.TypeOf(Contract{}): {},
- reflect.TypeOf(Dictionary{}): {},
- reflect.TypeOf(Event{}): {},
- reflect.TypeOf(Resource{}): {},
- reflect.TypeOf(Struct{}): {},
- }
-
- var valueInterface Value
- valueInterfaceType := reflect.TypeOf(&valueInterface).Elem()
+ test := func(name string, testCase valueTestCase) {
- checkedTypes := map[Type]struct{}{}
+ t.Run(name, func(t *testing.T) {
- sections, offsets := typelinks()
- for i, base := range sections {
- for _, offset := range offsets[i] {
- typeAddr := add(base, uintptr(offset), "")
- valueType := reflect.TypeOf(*(*interface{})(unsafe.Pointer(&typeAddr)))
+ value := testCase.value
- if !valueType.Implements(valueInterfaceType) {
- continue
- }
+ returnedType := value.Type()
- valueType = valueType.Elem()
+ expectedType := testCase.expectedType
+ if expectedType != nil {
+ require.NotNil(t, returnedType)
+ require.True(t, returnedType != nil)
+ require.Equal(t, expectedType, returnedType)
+ } else if !testCase.noType {
+ exampleType := testCase.exampleType
+ require.NotNil(t, exampleType)
- if _, ok := complexTypes[valueType]; ok {
- continue
- }
+ // Ensure the nil type is an *untyped nil*
+ require.Nil(t, returnedType)
+ require.True(t, returnedType == nil)
- valueInstance := reflect.New(valueType)
- value := valueInstance.Elem().Interface().(Value)
+ // Once a type is set, it should be returned
+ value = testCase.withType(value, exampleType)
- // Check whether the type is always returned
- cadenceType := value.Type()
- assert.NotNil(t, cadenceType)
+ returnedType = value.Type()
- // Check if the type is not a duplicate of some other type
- // i.e: two values can't return the same type.
- assert.NotContains(t, checkedTypes, cadenceType)
- checkedTypes[cadenceType] = struct{}{}
+ require.NotNil(t, returnedType)
+ require.Equal(t, exampleType, returnedType)
}
- }
- })
- t.Run("array value", func(t *testing.T) {
- t.Parallel()
-
- typ := NewConstantSizedArrayType(4, TheInt8Type)
- arrayValue := NewArray([]Value{}).WithType(typ)
- assert.Equal(t, arrayValue.Type(), typ)
- })
-
- t.Run("contract value", func(t *testing.T) {
- t.Parallel()
-
- typ := NewContractType(nil, "Foo", nil, nil)
- value := NewContract([]Value{}).WithType(typ)
- assert.Equal(t, typ, value.Type())
- })
-
- t.Run("dictionary value", func(t *testing.T) {
- t.Parallel()
-
- typ := NewDictionaryType(TheInt8Type, TheStringType)
- value := NewDictionary([]KeyValuePair{}).WithType(typ)
- assert.Equal(t, typ, value.Type())
- })
-
- t.Run("event value", func(t *testing.T) {
- t.Parallel()
-
- typ := NewEventType(nil, "Foo", nil, nil)
- value := NewEvent([]Value{}).WithType(typ)
- assert.Equal(t, typ, value.Type())
- })
-
- t.Run("resource value", func(t *testing.T) {
- t.Parallel()
-
- typ := NewResourceType(nil, "Foo", nil, nil)
- value := NewResource([]Value{}).WithType(typ)
- assert.Equal(t, typ, value.Type())
- })
-
- t.Run("struct value", func(t *testing.T) {
- t.Parallel()
+ // Check if the type is not a duplicate of some other type
+ // i.e: two values can't return the same type.
+ require.NotContains(t, checkedTypes, returnedType)
+ checkedTypes[returnedType] = struct{}{}
+ })
+ }
- typ := NewStructType(nil, "Foo", nil, nil)
- value := NewStruct([]Value{}).WithType(typ)
- assert.Equal(t, typ, value.Type())
- })
+ for name, testCase := range newValueTestCases() {
+ test(name, testCase)
+ }
}
diff --git a/version.go b/version.go
index 20aa2c8860..dfa632ff30 100644
--- a/version.go
+++ b/version.go
@@ -21,4 +21,4 @@
package cadence
-const Version = "v0.35.0"
+const Version = "v0.37.0"