Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Type.address and Type.contractName #3570

Merged
merged 3 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions runtime/interpreter/value_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
package interpreter

import (
"strings"

"github.com/onflow/atree"

"github.com/onflow/cadence/runtime/common"
Expand Down Expand Up @@ -172,6 +174,67 @@
}

return AsBoolValue(elaboration.IsRecovered)

case sema.MetaTypeAddressFieldName:
staticType := v.Type
if staticType == nil {
return Nil
}

location, _, err := common.DecodeTypeID(interpreter, string(staticType.ID()))
if err != nil || location == nil {
return Nil
}
SupunS marked this conversation as resolved.
Show resolved Hide resolved

addressLocation, ok := location.(common.AddressLocation)
if !ok {
return Nil
}

addressValue := NewAddressValue(
interpreter,
addressLocation.Address,
)
return NewSomeValueNonCopying(
interpreter,
addressValue,
)

case sema.MetaTypeContractNameFieldName:
staticType := v.Type
if staticType == nil {
return Nil
}

location, qualifiedIdentifier, err := common.DecodeTypeID(interpreter, string(staticType.ID()))
if err != nil || location == nil {
return Nil
}

switch location.(type) {
case common.AddressLocation,
common.StringLocation:

separatorIndex := strings.Index(qualifiedIdentifier, ".")
contractNameLength := len(qualifiedIdentifier)
if separatorIndex >= 0 {
contractNameLength = separatorIndex
}

contractNameValue := NewStringValue(
interpreter,
common.NewStringMemoryUsage(contractNameLength),
func() string {
return qualifiedIdentifier[0:contractNameLength]
},
)

return NewSomeValueNonCopying(interpreter, contractNameValue)

default:
return Nil

Check warning on line 235 in runtime/interpreter/value_type.go

View check run for this annotation

Codecov / codecov/patch

runtime/interpreter/value_type.go#L234-L235

Added lines #L234 - L235 were not covered by tests
SupunS marked this conversation as resolved.
Show resolved Hide resolved
}

}

return nil
Expand Down
32 changes: 32 additions & 0 deletions runtime/sema/meta_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,26 @@ const metaTypeIsRecoveredFieldDocString = `
The type was defined through a recovered program
`

const MetaTypeAddressFieldName = "address"

var MetaTypeAddressFieldType = &OptionalType{
Type: TheAddressType,
}

const metaTypeAddressFieldDocString = `
The address of the type, if it was declared in a contract deployed to an account
`

const MetaTypeContractNameFieldName = "contractName"

var MetaTypeContractNameFieldType = &OptionalType{
Type: StringType,
}

const metaTypeContractNameFieldDocString = `
The contract name of the type, if it was declared in a contract
`

func init() {
MetaType.Members = func(t *SimpleType) map[string]MemberResolver {
return MembersAsResolvers([]*Member{
Expand All @@ -90,6 +110,18 @@ func init() {
MetaTypeIsRecoveredFieldType,
metaTypeIsRecoveredFieldDocString,
),
NewUnmeteredPublicConstantFieldMember(
t,
MetaTypeAddressFieldName,
MetaTypeAddressFieldType,
metaTypeAddressFieldDocString,
),
NewUnmeteredPublicConstantFieldMember(
t,
MetaTypeContractNameFieldName,
MetaTypeContractNameFieldType,
metaTypeContractNameFieldDocString,
),
})
}
}
21 changes: 21 additions & 0 deletions runtime/tests/checker/metatype_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,27 @@ func TestCheckMetaTypeIsRecovered(t *testing.T) {
let type: Type = Type<Int>()
let isRecovered: Bool = type.isRecovered
`)
require.NoError(t, err)
}

func TestCheckMetaTypeAddress(t *testing.T) {

t.Parallel()

_, err := ParseAndCheck(t, `
let type: Type = Type<Int>()
let address: Address = type.address!
`)
require.NoError(t, err)
}

func TestCheckMetaTypeContractName(t *testing.T) {

t.Parallel()

_, err := ParseAndCheck(t, `
let type: Type = Type<Int>()
let contractName: String = type.contractName!
`)
require.NoError(t, err)
}
Loading
Loading