diff --git a/runtime/cmd/cmd.go b/runtime/cmd/cmd.go index 2a3c8e6797..974ce4f7a9 100644 --- a/runtime/cmd/cmd.go +++ b/runtime/cmd/cmd.go @@ -92,8 +92,10 @@ func DefaultCheckerConfig( baseValueActivation.DeclareValue(stdlib.NewLogFunction(StandardOutputLogger{})) return &sema.Config{ - BaseValueActivation: baseValueActivation, - AccessCheckMode: sema.AccessCheckModeStrict, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + AccessCheckMode: sema.AccessCheckModeStrict, ImportHandler: func( checker *sema.Checker, importedLocation common.Location, @@ -192,8 +194,10 @@ func PrepareInterpreter(filename string, debugger *interpreter.Debugger) (*inter interpreter.Declare(baseActivation, stdlib.NewLogFunction(StandardOutputLogger{})) config := &interpreter.Config{ - BaseActivation: baseActivation, - Storage: storage, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, + Storage: storage, UUIDHandler: func() (uint64, error) { defer func() { uuid++ }() return uuid, nil diff --git a/runtime/environment.go b/runtime/environment.go index df4b5e8f7b..426f38dcfe 100644 --- a/runtime/environment.go +++ b/runtime/environment.go @@ -38,8 +38,14 @@ import ( type Environment interface { ArgumentDecoder - DeclareValue(valueDeclaration stdlib.StandardLibraryValue) - DeclareType(typeDeclaration stdlib.StandardLibraryType) + DeclareValue( + valueDeclaration stdlib.StandardLibraryValue, + location common.Location, + ) + DeclareType( + typeDeclaration stdlib.StandardLibraryType, + location common.Location, + ) Configure( runtimeInterface Interface, codesAndPrograms CodesAndPrograms, @@ -79,9 +85,37 @@ type interpreterEnvironmentReconfigured struct { type interpreterEnvironment struct { interpreterEnvironmentReconfigured - baseTypeActivation *sema.VariableActivation - baseValueActivation *sema.VariableActivation - baseActivation *interpreter.VariableActivation + + // defaultBaseTypeActivation is the base type activation that applies to all locations by default. + defaultBaseTypeActivation *sema.VariableActivation + // The base type activations for individual locations. + // location == nil is the base type activation that applies to all locations, + // unless there is a base type activation for the given location. + // + // Base type activations are lazily / implicitly created + // by DeclareType / semaBaseActivationFor + baseTypeActivationsByLocation map[common.Location]*sema.VariableActivation + + // defaultBaseValueActivation is the base value activation that applies to all locations by default. + defaultBaseValueActivation *sema.VariableActivation + // The base value activations for individual locations. + // location == nil is the base value activation that applies to all locations, + // unless there is a base value activation for the given location. + // + // Base value activations are lazily / implicitly created + // by DeclareValue / semaBaseActivationFor + baseValueActivationsByLocation map[common.Location]*sema.VariableActivation + + // defaultBaseActivation is the base activation that applies to all locations by default + defaultBaseActivation *interpreter.VariableActivation + // The base activations for individual locations. + // location == nil is the base activation that applies to all locations, + // unless there is a base activation for the given location. + // + // Base activations are lazily / implicitly created + // by DeclareValue / interpreterBaseActivationFor + baseActivationsByLocation map[common.Location]*interpreter.VariableActivation + InterpreterConfig *interpreter.Config CheckerConfig *sema.Config deployedContractConstructorInvocation *stdlib.DeployedContractConstructorInvocation @@ -109,16 +143,16 @@ var _ ArgumentDecoder = &interpreterEnvironment{} var _ common.MemoryGauge = &interpreterEnvironment{} func newInterpreterEnvironment(config Config) *interpreterEnvironment { - baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) - baseTypeActivation := sema.NewVariableActivation(sema.BaseTypeActivation) - baseActivation := activations.NewActivation[*interpreter.Variable](nil, interpreter.BaseActivation) + defaultBaseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) + defaultBaseTypeActivation := sema.NewVariableActivation(sema.BaseTypeActivation) + defaultBaseActivation := activations.NewActivation(nil, interpreter.BaseActivation) env := &interpreterEnvironment{ - config: config, - baseValueActivation: baseValueActivation, - baseTypeActivation: baseTypeActivation, - baseActivation: baseActivation, - stackDepthLimiter: newStackDepthLimiter(config.StackDepthLimit), + config: config, + defaultBaseValueActivation: defaultBaseValueActivation, + defaultBaseTypeActivation: defaultBaseTypeActivation, + defaultBaseActivation: defaultBaseActivation, + stackDepthLimiter: newStackDepthLimiter(config.StackDepthLimit), } env.InterpreterConfig = env.newInterpreterConfig() env.CheckerConfig = env.newCheckerConfig() @@ -129,7 +163,7 @@ func (e *interpreterEnvironment) newInterpreterConfig() *interpreter.Config { return &interpreter.Config{ InvalidatedResourceValidationEnabled: true, MemoryGauge: e, - BaseActivation: e.baseActivation, + BaseActivationHandler: e.getBaseActivation, OnEventEmitted: e.newOnEventEmittedHandler(), OnAccountLinked: e.newOnAccountLinkedHandler(), InjectedCompositeFieldsHandler: e.newInjectedCompositeFieldsHandler(), @@ -161,8 +195,8 @@ func (e *interpreterEnvironment) newInterpreterConfig() *interpreter.Config { func (e *interpreterEnvironment) newCheckerConfig() *sema.Config { return &sema.Config{ AccessCheckMode: sema.AccessCheckModeStrict, - BaseValueActivation: e.baseValueActivation, - BaseTypeActivation: e.baseTypeActivation, + BaseValueActivationHandler: e.getBaseValueActivation, + BaseTypeActivationHandler: e.getBaseTypeActivation, ValidTopLevelDeclarationsHandler: validTopLevelDeclarations, LocationHandler: e.newLocationHandler(), ImportHandler: e.resolveImport, @@ -176,7 +210,7 @@ func (e *interpreterEnvironment) newCheckerConfig() *sema.Config { func NewBaseInterpreterEnvironment(config Config) *interpreterEnvironment { env := newInterpreterEnvironment(config) for _, valueDeclaration := range stdlib.DefaultStandardLibraryValues(env) { - env.DeclareValue(valueDeclaration) + env.DeclareValue(valueDeclaration, nil) } return env } @@ -184,7 +218,7 @@ func NewBaseInterpreterEnvironment(config Config) *interpreterEnvironment { func NewScriptInterpreterEnvironment(config Config) Environment { env := newInterpreterEnvironment(config) for _, valueDeclaration := range stdlib.DefaultScriptStandardLibraryValues(env) { - env.DeclareValue(valueDeclaration) + env.DeclareValue(valueDeclaration, nil) } return env } @@ -203,13 +237,63 @@ func (e *interpreterEnvironment) Configure( e.stackDepthLimiter.depth = 0 } -func (e *interpreterEnvironment) DeclareValue(valueDeclaration stdlib.StandardLibraryValue) { - e.baseValueActivation.DeclareValue(valueDeclaration) - interpreter.Declare(e.baseActivation, valueDeclaration) +func (e *interpreterEnvironment) DeclareValue(valueDeclaration stdlib.StandardLibraryValue, location common.Location) { + e.semaBaseActivationFor( + location, + &e.baseValueActivationsByLocation, + e.defaultBaseValueActivation, + ).DeclareValue(valueDeclaration) + + activation := e.interpreterBaseActivationFor(location) + interpreter.Declare(activation, valueDeclaration) +} + +func (e *interpreterEnvironment) DeclareType(typeDeclaration stdlib.StandardLibraryType, location common.Location) { + e.semaBaseActivationFor( + location, + &e.baseTypeActivationsByLocation, + e.defaultBaseTypeActivation, + ).DeclareType(typeDeclaration) } -func (e *interpreterEnvironment) DeclareType(typeDeclaration stdlib.StandardLibraryType) { - e.baseTypeActivation.DeclareType(typeDeclaration) +func (e *interpreterEnvironment) semaBaseActivationFor( + location common.Location, + baseActivationsByLocation *map[Location]*sema.VariableActivation, + defaultBaseActivation *sema.VariableActivation, +) (baseActivation *sema.VariableActivation) { + if location == nil { + return defaultBaseActivation + } + + if *baseActivationsByLocation == nil { + *baseActivationsByLocation = map[Location]*sema.VariableActivation{} + } else { + baseActivation = (*baseActivationsByLocation)[location] + } + if baseActivation == nil { + baseActivation = sema.NewVariableActivation(defaultBaseActivation) + (*baseActivationsByLocation)[location] = baseActivation + } + return baseActivation +} + +func (e *interpreterEnvironment) interpreterBaseActivationFor( + location common.Location, +) *interpreter.VariableActivation { + defaultBaseActivation := e.defaultBaseActivation + if location == nil { + return defaultBaseActivation + } + + baseActivation := e.baseActivationsByLocation[location] + if baseActivation == nil { + baseActivation = activations.NewActivation[*interpreter.Variable](nil, defaultBaseActivation) + if e.baseActivationsByLocation == nil { + e.baseActivationsByLocation = map[common.Location]*interpreter.VariableActivation{} + } + e.baseActivationsByLocation[location] = baseActivation + } + return baseActivation } func (e *interpreterEnvironment) NewAuthAccountValue(address interpreter.AddressValue) interpreter.Value { @@ -908,7 +992,8 @@ func (e *interpreterEnvironment) newCompositeTypeHandler() interpreter.Composite case nil: qualifiedIdentifier := string(typeID) - ty := sema.TypeActivationNestedType(e.baseTypeActivation, qualifiedIdentifier) + baseTypeActivation := e.getBaseTypeActivation(location) + ty := sema.TypeActivationNestedType(baseTypeActivation, qualifiedIdentifier) if ty == nil { return nil } @@ -1096,3 +1181,70 @@ func (e *interpreterEnvironment) CommitStorage(inter *interpreter.Interpreter) e return nil } + +// getBaseValueActivation returns the base activation for the given location. +// If a value was declared for the location (using DeclareValue), +// then the specific base value activation for this location is returned. +// Otherwise, the default base activation that applies for all locations is returned. +func (e *interpreterEnvironment) getBaseValueActivation( + location common.Location, +) ( + baseValueActivation *sema.VariableActivation, +) { + baseValueActivationsByLocation := e.baseValueActivationsByLocation + // Use the base value activation for the location, if any + // (previously implicitly created using DeclareValue) + baseValueActivation = baseValueActivationsByLocation[location] + if baseValueActivation == nil { + // If no base value activation for the location exists + // (no value was previously, specifically declared for the location using DeclareValue), + // return the base value activation that applies to all locations by default + baseValueActivation = e.defaultBaseValueActivation + } + return + +} + +// getBaseTypeActivation returns the base activation for the given location. +// If a type was declared for the location (using DeclareType), +// then the specific base type activation for this location is returned. +// Otherwise, the default base activation that applies for all locations is returned. +func (e *interpreterEnvironment) getBaseTypeActivation( + location common.Location, +) ( + baseTypeActivation *sema.VariableActivation, +) { + // Use the base type activation for the location, if any + // (previously implicitly created using DeclareType) + baseTypeActivationsByLocation := e.baseTypeActivationsByLocation + baseTypeActivation = baseTypeActivationsByLocation[location] + if baseTypeActivation == nil { + // If no base type activation for the location exists + // (no type was previously, specifically declared for the location using DeclareType), + // return the base type activation that applies to all locations by default + baseTypeActivation = e.defaultBaseTypeActivation + } + return +} + +// getBaseActivation returns the base activation for the given location. +// If a value was declared for the location (using DeclareValue), +// then the specific base activation for this location is returned. +// Otherwise, the default base activation that applies for all locations is returned. +func (e *interpreterEnvironment) getBaseActivation( + location common.Location, +) ( + baseActivation *interpreter.VariableActivation, +) { + // Use the base activation for the location, if any + // (previously implicitly created using DeclareValue) + baseActivationsByLocation := e.baseActivationsByLocation + baseActivation = baseActivationsByLocation[location] + if baseActivation == nil { + // If no base activation for the location exists + // (no value was previously, specifically declared for the location using DeclareValue), + // return the base activation that applies to all locations by default + baseActivation = e.defaultBaseActivation + } + return +} diff --git a/runtime/interpreter/config.go b/runtime/interpreter/config.go index cc5262da5d..cf888fc060 100644 --- a/runtime/interpreter/config.go +++ b/runtime/interpreter/config.go @@ -50,9 +50,9 @@ type Config struct { // UUIDHandler is used to handle the generation of UUIDs UUIDHandler UUIDHandlerFunc // CompositeTypeHandler is used to load composite types - CompositeTypeHandler CompositeTypeHandlerFunc - BaseActivation *VariableActivation - Debugger *Debugger + CompositeTypeHandler CompositeTypeHandlerFunc + BaseActivationHandler func(location common.Location) *VariableActivation + Debugger *Debugger // OnStatement is triggered when a statement is about to be executed OnStatement OnStatementFunc // OnLoopIteration is triggered when a loop iteration is about to be executed diff --git a/runtime/interpreter/interpreter.go b/runtime/interpreter/interpreter.go index de338e7b8d..33b7c35d5d 100644 --- a/runtime/interpreter/interpreter.go +++ b/runtime/interpreter/interpreter.go @@ -296,9 +296,15 @@ func NewInterpreterWithSharedState( sharedState.allInterpreters[location] = interpreter } + // Initialize activations + interpreter.activations = activations.NewActivations[*Variable](interpreter) - baseActivation := sharedState.Config.BaseActivation + var baseActivation *VariableActivation + baseActivationHandler := sharedState.Config.BaseActivationHandler + if baseActivationHandler != nil { + baseActivation = baseActivationHandler(location) + } if baseActivation == nil { baseActivation = BaseActivation } diff --git a/runtime/predeclaredvalues_test.go b/runtime/predeclaredvalues_test.go index 57a86788e4..36de67f4f9 100644 --- a/runtime/predeclaredvalues_test.go +++ b/runtime/predeclaredvalues_test.go @@ -22,6 +22,7 @@ import ( "math/big" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/onflow/cadence" @@ -29,6 +30,7 @@ import ( "github.com/onflow/cadence/runtime/interpreter" "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" + "github.com/onflow/cadence/runtime/tests/checker" . "github.com/onflow/cadence/runtime/tests/utils" ) @@ -36,96 +38,218 @@ func TestRuntimePredeclaredValues(t *testing.T) { t.Parallel() - valueDeclaration := stdlib.StandardLibraryValue{ - Name: "foo", - Type: sema.IntType, - Kind: common.DeclarationKindConstant, - Value: interpreter.NewUnmeteredIntValueFromInt64(2), + const contractName = "C" + address := common.MustBytesToAddress([]byte{0x1}) + contractLocation := common.AddressLocation{ + Address: address, + Name: contractName, } - contract := []byte(` - pub contract C { - pub fun foo(): Int { - return foo - } - } - `) - - script := []byte(` - import C from 0x1 - - pub fun main(): Int { - return foo + C.foo() - } - `) - - runtime := newTestInterpreterRuntime() - - deploy := DeploymentTransaction("C", contract) - - var accountCode []byte - var events []cadence.Event - - runtimeInterface := &testRuntimeInterface{ - getCode: func(_ Location) (bytes []byte, err error) { - return accountCode, nil - }, - storage: newTestLedger(nil, nil), - getSigningAccounts: func() ([]Address, error) { - return []Address{common.MustBytesToAddress([]byte{0x1})}, nil - }, - resolveLocation: singleIdentifierLocationResolver(t), - getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) { - return accountCode, nil - }, - updateAccountContractCode: func(_ common.AddressLocation, code []byte) error { - accountCode = code - return nil - }, - emitEvent: func(event cadence.Event) error { - events = append(events, event) - return nil - }, + test := func( + t *testing.T, + contract string, + script string, + valueDeclarations map[common.Location]stdlib.StandardLibraryValue, + checkTransaction func(err error) bool, + checkScript func(result cadence.Value, err error), + ) { + + runtime := newTestInterpreterRuntime() + + deploy := DeploymentTransaction(contractName, []byte(contract)) + + var accountCode []byte + var events []cadence.Event + + runtimeInterface := &testRuntimeInterface{ + getCode: func(_ Location) (bytes []byte, err error) { + return accountCode, nil + }, + storage: newTestLedger(nil, nil), + getSigningAccounts: func() ([]Address, error) { + return []Address{address}, nil + }, + resolveLocation: singleIdentifierLocationResolver(t), + getAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) { + return accountCode, nil + }, + updateAccountContractCode: func(_ common.AddressLocation, code []byte) error { + accountCode = code + return nil + }, + emitEvent: func(event cadence.Event) error { + events = append(events, event) + return nil + }, + } + + prepareEnvironment := func(env Environment) { + for location, valueDeclaration := range valueDeclarations { + env.DeclareValue(valueDeclaration, location) + } + } + + // Run deploy transaction + + transactionEnvironment := NewBaseInterpreterEnvironment(Config{}) + prepareEnvironment(transactionEnvironment) + + err := runtime.ExecuteTransaction( + Script{ + Source: deploy, + }, + Context{ + Interface: runtimeInterface, + Location: common.TransactionLocation{}, + Environment: transactionEnvironment, + }, + ) + + if checkTransaction(err) { + + scriptEnvironment := NewScriptInterpreterEnvironment(Config{}) + prepareEnvironment(scriptEnvironment) + + checkScript(runtime.ExecuteScript( + Script{ + Source: []byte(script), + }, + Context{ + Interface: runtimeInterface, + Location: common.ScriptLocation{}, + Environment: scriptEnvironment, + }, + )) + } } - // Run transaction - - transactionEnvironment := NewBaseInterpreterEnvironment(Config{}) - transactionEnvironment.DeclareValue(valueDeclaration) - - err := runtime.ExecuteTransaction( - Script{ - Source: deploy, - }, - Context{ - Interface: runtimeInterface, - Location: common.TransactionLocation{}, - Environment: transactionEnvironment, - }, - ) - require.NoError(t, err) - - // Run script - - scriptEnvironment := NewScriptInterpreterEnvironment(Config{}) - scriptEnvironment.DeclareValue(valueDeclaration) - - result, err := runtime.ExecuteScript( - Script{ - Source: script, - }, - Context{ - Interface: runtimeInterface, - Location: common.ScriptLocation{}, - Environment: scriptEnvironment, - }, - ) - require.NoError(t, err) - - require.Equal(t, - cadence.Int{Value: big.NewInt(4)}, - result, - ) + t.Run("everywhere", func(t *testing.T) { + t.Parallel() + + test(t, + ` + pub contract C { + pub fun foo(): Int { + return foo + } + } + `, + ` + import C from 0x1 + + pub fun main(): Int { + return foo + C.foo() + } + `, + map[common.Location]stdlib.StandardLibraryValue{ + nil: { + Name: "foo", + Type: sema.IntType, + Kind: common.DeclarationKindConstant, + Value: interpreter.NewUnmeteredIntValueFromInt64(2), + }, + }, + func(err error) bool { + return assert.NoError(t, err) + }, + func(result cadence.Value, err error) { + + require.NoError(t, err) + + require.Equal(t, + cadence.Int{Value: big.NewInt(4)}, + result, + ) + }, + ) + }) + + t.Run("only contract, no use in script", func(t *testing.T) { + t.Parallel() + + test(t, + ` + pub contract C { + pub fun foo(): Int { + return foo + } + } + `, + ` + import C from 0x1 + + pub fun main(): Int { + return C.foo() + } + `, + map[common.Location]stdlib.StandardLibraryValue{ + contractLocation: { + Name: "foo", + Type: sema.IntType, + Kind: common.DeclarationKindConstant, + Value: interpreter.NewUnmeteredIntValueFromInt64(2), + }, + }, + func(err error) bool { + return assert.NoError(t, err) + }, + func(result cadence.Value, err error) { + + require.NoError(t, err) + + require.Equal(t, + cadence.Int{Value: big.NewInt(2)}, + result, + ) + }, + ) + }) + + t.Run("only contract, use in script", func(t *testing.T) { + t.Parallel() + + test(t, + ` + pub contract C { + pub fun foo(): Int { + return foo + } + } + `, + ` + import C from 0x1 + + pub fun main(): Int { + return foo + C.foo() + } + `, + map[common.Location]stdlib.StandardLibraryValue{ + contractLocation: { + Name: "foo", + Type: sema.IntType, + Kind: common.DeclarationKindConstant, + Value: interpreter.NewUnmeteredIntValueFromInt64(2), + }, + }, + func(err error) bool { + return assert.NoError(t, err) + }, + func(result cadence.Value, err error) { + RequireError(t, err) + + var checkerErr *sema.CheckerError + require.ErrorAs(t, err, &checkerErr) + assert.Equal(t, common.ScriptLocation{}, checkerErr.Location) + + errs := checker.RequireCheckerErrors(t, err, 1) + + var notDeclaredErr *sema.NotDeclaredError + require.ErrorAs(t, errs[0], ¬DeclaredErr) + require.Equal(t, "foo", notDeclaredErr.Name) + }, + ) + }) + } func TestRuntimePredeclaredTypes(t *testing.T) { @@ -169,8 +293,8 @@ func TestRuntimePredeclaredTypes(t *testing.T) { // Run script scriptEnvironment := NewScriptInterpreterEnvironment(Config{}) - scriptEnvironment.DeclareValue(valueDeclaration) - scriptEnvironment.DeclareType(typeDeclaration) + scriptEnvironment.DeclareValue(valueDeclaration, nil) + scriptEnvironment.DeclareType(typeDeclaration, nil) result, err := runtime.ExecuteScript( Script{ @@ -239,8 +363,8 @@ func TestRuntimePredeclaredTypes(t *testing.T) { // Run script scriptEnvironment := NewScriptInterpreterEnvironment(Config{}) - scriptEnvironment.DeclareValue(valueDeclaration) - scriptEnvironment.DeclareType(typeDeclaration) + scriptEnvironment.DeclareValue(valueDeclaration, nil) + scriptEnvironment.DeclareType(typeDeclaration, nil) result, err := runtime.ExecuteScript( Script{ @@ -308,7 +432,7 @@ func TestRuntimePredeclaredTypes(t *testing.T) { // Run script scriptEnvironment := NewScriptInterpreterEnvironment(Config{}) - scriptEnvironment.DeclareValue(valueDeclaration) + scriptEnvironment.DeclareValue(valueDeclaration, nil) _, err := runtime.ExecuteScript( Script{ @@ -383,8 +507,8 @@ func TestRuntimePredeclaredTypes(t *testing.T) { // Run script scriptEnvironment := NewScriptInterpreterEnvironment(Config{}) - scriptEnvironment.DeclareValue(valueDeclaration) - scriptEnvironment.DeclareType(typeDeclaration) + scriptEnvironment.DeclareValue(valueDeclaration, nil) + scriptEnvironment.DeclareType(typeDeclaration, nil) result, err := runtime.ExecuteScript( Script{ @@ -460,7 +584,7 @@ func TestRuntimePredeclaredTypes(t *testing.T) { // Run script scriptEnvironment := NewScriptInterpreterEnvironment(Config{}) - scriptEnvironment.DeclareValue(valueDeclaration) + scriptEnvironment.DeclareValue(valueDeclaration, nil) _, err := runtime.ExecuteScript( Script{ diff --git a/runtime/repl.go b/runtime/repl.go index 30e70a39d7..e148800619 100644 --- a/runtime/repl.go +++ b/runtime/repl.go @@ -80,7 +80,9 @@ func NewREPL() (*REPL, error) { defer func() { uuid++ }() return uuid, nil }, - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, } inter, err := interpreter.NewInterpreter( diff --git a/runtime/sema/checker.go b/runtime/sema/checker.go index ae7626a8e2..e584939483 100644 --- a/runtime/sema/checker.go +++ b/runtime/sema/checker.go @@ -66,7 +66,9 @@ var beforeType = func() *FunctionType { } }() -type ValidTopLevelDeclarationsHandlerFunc = func(common.Location) common.DeclarationKindSet +type ValidTopLevelDeclarationsHandlerFunc func(common.Location) common.DeclarationKindSet + +type ActivationHandlerFunc func(common.Location) *VariableActivation type CheckHandlerFunc func(checker *Checker, check func()) @@ -119,6 +121,21 @@ var _ ast.DeclarationVisitor[struct{}] = &Checker{} var _ ast.StatementVisitor[struct{}] = &Checker{} var _ ast.ExpressionVisitor[Type] = &Checker{} +func NewVariableActivationsFromHandler( + handler ActivationHandlerFunc, + location common.Location, + defaultActivation *VariableActivation, +) *VariableActivations { + var activation *VariableActivation + if handler != nil { + activation = handler(location) + } + if activation == nil { + activation = defaultActivation + } + return NewVariableActivations(activation) +} + func NewChecker( program *ast.Program, location common.Location, @@ -160,19 +177,19 @@ func NewChecker( // Initialize value activations - baseValueActivation := config.BaseValueActivation - if baseValueActivation == nil { - baseValueActivation = BaseValueActivation - } - checker.valueActivations = NewVariableActivations(baseValueActivation) + checker.valueActivations = NewVariableActivationsFromHandler( + config.BaseValueActivationHandler, + location, + BaseValueActivation, + ) // Initialize type activations - baseTypeActivation := config.BaseTypeActivation - if baseTypeActivation == nil { - baseTypeActivation = BaseTypeActivation - } - checker.typeActivations = NewVariableActivations(baseTypeActivation) + checker.typeActivations = NewVariableActivationsFromHandler( + config.BaseTypeActivationHandler, + location, + BaseTypeActivation, + ) // Initialize position info, if enabled if checker.Config.PositionInfoEnabled { diff --git a/runtime/sema/config.go b/runtime/sema/config.go index d651c0d884..135bdf444b 100644 --- a/runtime/sema/config.go +++ b/runtime/sema/config.go @@ -26,10 +26,10 @@ type Config struct { // ValidTopLevelDeclarationsHandler is used to determine the kinds of declarations // which are valid at the top-level for a given location ValidTopLevelDeclarationsHandler ValidTopLevelDeclarationsHandlerFunc - BaseTypeActivation *VariableActivation + BaseTypeActivationHandler ActivationHandlerFunc + BaseValueActivationHandler ActivationHandlerFunc // ImportHandler is used to resolve unresolved imports - ImportHandler ImportHandlerFunc - BaseValueActivation *VariableActivation + ImportHandler ImportHandlerFunc // CheckHandler is the function which is used for the checking of a program CheckHandler CheckHandlerFunc // LocationHandler is used to resolve locations diff --git a/runtime/stdlib/builtin_test.go b/runtime/stdlib/builtin_test.go index d0efd6c0a0..834c98e997 100644 --- a/runtime/stdlib/builtin_test.go +++ b/runtime/stdlib/builtin_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/onflow/cadence/runtime/activations" + "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/tests/checker" "github.com/stretchr/testify/assert" @@ -55,8 +56,10 @@ func newInterpreter(t *testing.T, code string, valueDeclarations ...StandardLibr utils.TestLocation, nil, &sema.Config{ - BaseValueActivation: baseValueActivation, - AccessCheckMode: sema.AccessCheckModeStrict, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + AccessCheckMode: sema.AccessCheckModeStrict, }, ) require.NoError(t, err) @@ -75,8 +78,10 @@ func newInterpreter(t *testing.T, code string, valueDeclarations ...StandardLibr interpreter.ProgramFromChecker(checker), checker.Location, &interpreter.Config{ - Storage: storage, - BaseActivation: baseActivation, + Storage: storage, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, ) require.NoError(t, err) @@ -99,7 +104,9 @@ func TestCheckAssert(t *testing.T) { code, checker.ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -215,7 +222,9 @@ func TestCheckPanic(t *testing.T) { code, checker.ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) diff --git a/runtime/stdlib/test_contract.go b/runtime/stdlib/test_contract.go index 3a7bcd12fb..abe27d898d 100644 --- a/runtime/stdlib/test_contract.go +++ b/runtime/stdlib/test_contract.go @@ -965,8 +965,10 @@ func newTestContractType() *TestContractType { TestContractLocation, nil, &sema.Config{ - BaseValueActivation: activation, - AccessCheckMode: sema.AccessCheckModeStrict, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return activation + }, + AccessCheckMode: sema.AccessCheckModeStrict, }, ) if err != nil { diff --git a/runtime/stdlib/test_test.go b/runtime/stdlib/test_test.go index de5545174a..1b1c8c6f2c 100644 --- a/runtime/stdlib/test_test.go +++ b/runtime/stdlib/test_test.go @@ -61,17 +61,19 @@ func newTestContractInterpreterWithTestFramework( ) require.NoError(t, err) - activation := sema.NewVariableActivation(sema.BaseValueActivation) - activation.DeclareValue(stdlib.AssertFunction) - activation.DeclareValue(stdlib.PanicFunction) + baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) + baseValueActivation.DeclareValue(stdlib.AssertFunction) + baseValueActivation.DeclareValue(stdlib.PanicFunction) checker, err := sema.NewChecker( program, utils.TestLocation, nil, &sema.Config{ - BaseValueActivation: activation, - AccessCheckMode: sema.AccessCheckModeStrict, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + AccessCheckMode: sema.AccessCheckModeStrict, ImportHandler: func( checker *sema.Checker, importedLocation common.Location, @@ -110,8 +112,10 @@ func newTestContractInterpreterWithTestFramework( interpreter.ProgramFromChecker(checker), checker.Location, &interpreter.Config{ - Storage: storage, - BaseActivation: baseActivation, + Storage: storage, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, ImportLocationHandler: func(inter *interpreter.Interpreter, location common.Location) interpreter.Import { if location == stdlib.TestContractLocation { program := interpreter.ProgramFromChecker(stdlib.GetTestContractType().Checker) diff --git a/runtime/tests/checker/account_test.go b/runtime/tests/checker/account_test.go index 806bb5b1a7..12ace1b81b 100644 --- a/runtime/tests/checker/account_test.go +++ b/runtime/tests/checker/account_test.go @@ -40,15 +40,14 @@ func ParseAndCheckAccountWithConfig(t *testing.T, code string, config sema.Confi } } - baseValueActivation := config.BaseValueActivation - if baseValueActivation == nil { - baseValueActivation = sema.BaseValueActivation - } - - baseValueActivation = sema.NewVariableActivation(baseValueActivation) + baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) baseValueActivation.DeclareValue(constantDeclaration("authAccount", sema.AuthAccountType)) baseValueActivation.DeclareValue(constantDeclaration("publicAccount", sema.PublicAccountType)) - config.BaseValueActivation = baseValueActivation + + require.Nil(t, config.BaseValueActivationHandler) + config.BaseValueActivationHandler = func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + } return ParseAndCheckWithOptions(t, code, diff --git a/runtime/tests/checker/assert_test.go b/runtime/tests/checker/assert_test.go index a726834519..31220d4f69 100644 --- a/runtime/tests/checker/assert_test.go +++ b/runtime/tests/checker/assert_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" ) @@ -42,7 +43,9 @@ func TestCheckAssertWithoutMessage(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -65,7 +68,9 @@ func TestCheckAssertWithMessage(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) diff --git a/runtime/tests/checker/capability_controller_test.go b/runtime/tests/checker/capability_controller_test.go index 4b94c86c53..6c98d810f1 100644 --- a/runtime/tests/checker/capability_controller_test.go +++ b/runtime/tests/checker/capability_controller_test.go @@ -44,7 +44,9 @@ func TestCheckStorageCapabilityController(t *testing.T) { code, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseActivation + }, }, }, ) @@ -105,7 +107,9 @@ func TestCheckAccountCapabilityController(t *testing.T) { code, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseActivation + }, }, }, ) diff --git a/runtime/tests/checker/crypto_test.go b/runtime/tests/checker/crypto_test.go index b7174e2e34..f512362247 100644 --- a/runtime/tests/checker/crypto_test.go +++ b/runtime/tests/checker/crypto_test.go @@ -24,6 +24,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" ) @@ -48,7 +49,9 @@ func TestCheckHashAlgorithmCases(t *testing.T) { ), ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -74,7 +77,9 @@ func TestCheckHashAlgorithmConstructor(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -97,7 +102,9 @@ func TestCheckHashAlgorithmHashFunctions(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -123,7 +130,9 @@ func TestCheckSignatureAlgorithmCases(t *testing.T) { ), ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -149,7 +158,9 @@ func TestCheckSignatureAlgorithmConstructor(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -176,7 +187,9 @@ func TestCheckVerifyPoP(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -203,7 +216,9 @@ func TestCheckVerifyPoPInvalidArgument(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -227,7 +242,9 @@ func TestCheckBLSAggregateSignatures(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -248,7 +265,9 @@ func TestCheckInvalidBLSAggregateSignatures(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -279,7 +298,9 @@ func TestCheckBLSAggregatePublicKeys(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -302,7 +323,9 @@ func TestCheckInvalidBLSAggregatePublicKeys(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) diff --git a/runtime/tests/checker/genericfunction_test.go b/runtime/tests/checker/genericfunction_test.go index d45e61a775..86b035e6ca 100644 --- a/runtime/tests/checker/genericfunction_test.go +++ b/runtime/tests/checker/genericfunction_test.go @@ -45,7 +45,9 @@ func parseAndCheckWithTestValue(t *testing.T, code string, ty sema.Type) (*sema. code, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) diff --git a/runtime/tests/checker/interface_test.go b/runtime/tests/checker/interface_test.go index 89059b6366..ed4f5ce9c0 100644 --- a/runtime/tests/checker/interface_test.go +++ b/runtime/tests/checker/interface_test.go @@ -1893,6 +1893,13 @@ func BenchmarkCheckContractInterfaceFungibleTokenConformance(b *testing.B) { baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) baseValueActivation.DeclareValue(stdlib.PanicFunction) + config := &sema.Config{ + AccessCheckMode: sema.AccessCheckModeNotSpecifiedUnrestricted, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + } + b.ReportAllocs() b.ResetTimer() @@ -1901,10 +1908,7 @@ func BenchmarkCheckContractInterfaceFungibleTokenConformance(b *testing.B) { program, TestLocation, nil, - &sema.Config{ - AccessCheckMode: sema.AccessCheckModeNotSpecifiedUnrestricted, - BaseValueActivation: baseValueActivation, - }, + config, ) if err != nil { b.Fatal(err) diff --git a/runtime/tests/checker/invocation_test.go b/runtime/tests/checker/invocation_test.go index f5f6239428..1e09f7a7c3 100644 --- a/runtime/tests/checker/invocation_test.go +++ b/runtime/tests/checker/invocation_test.go @@ -24,6 +24,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" ) @@ -332,7 +333,9 @@ func TestCheckInvocationWithOnlyVarargs(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) diff --git a/runtime/tests/checker/nesting_test.go b/runtime/tests/checker/nesting_test.go index 9fc3a7813e..da2e1c4005 100644 --- a/runtime/tests/checker/nesting_test.go +++ b/runtime/tests/checker/nesting_test.go @@ -320,7 +320,9 @@ func TestCheckNestedTypeInvalidChildType(t *testing.T) { `let u: T.U = nil`, ParseAndCheckOptions{ Config: &sema.Config{ - BaseTypeActivation: baseTypeActivation, + BaseTypeActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseTypeActivation + }, }, }, ) diff --git a/runtime/tests/checker/nft_test.go b/runtime/tests/checker/nft_test.go index d8461e8dd2..c03970a0e7 100644 --- a/runtime/tests/checker/nft_test.go +++ b/runtime/tests/checker/nft_test.go @@ -1003,7 +1003,9 @@ func TestCheckTopShotContract(t *testing.T) { Elaboration: nftChecker.Elaboration, }, nil }, - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) diff --git a/runtime/tests/checker/predeclaredvalues_test.go b/runtime/tests/checker/predeclaredvalues_test.go index e1e6cfd5c9..503216d796 100644 --- a/runtime/tests/checker/predeclaredvalues_test.go +++ b/runtime/tests/checker/predeclaredvalues_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" ) @@ -53,7 +54,9 @@ func TestCheckPredeclaredValues(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) diff --git a/runtime/tests/checker/return_test.go b/runtime/tests/checker/return_test.go index 046f3948fd..09075ffff0 100644 --- a/runtime/tests/checker/return_test.go +++ b/runtime/tests/checker/return_test.go @@ -25,6 +25,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" ) @@ -209,7 +210,9 @@ func testExits(t *testing.T, test exitTest) { code, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) diff --git a/runtime/tests/checker/rlp_test.go b/runtime/tests/checker/rlp_test.go index 65c93ef822..9b2c3950ac 100644 --- a/runtime/tests/checker/rlp_test.go +++ b/runtime/tests/checker/rlp_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" ) @@ -40,7 +41,9 @@ func TestCheckRLPDecodeString(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -60,7 +63,9 @@ func TestCheckInvalidRLPDecodeString(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -84,7 +89,9 @@ func TestCheckRLPDecodeList(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -104,7 +111,9 @@ func TestCheckInvalidRLPDecodeList(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) diff --git a/runtime/tests/checker/storable_test.go b/runtime/tests/checker/storable_test.go index 3f90ba4ecf..4b5eb7a327 100644 --- a/runtime/tests/checker/storable_test.go +++ b/runtime/tests/checker/storable_test.go @@ -44,8 +44,10 @@ func TestCheckStorable(t *testing.T) { code, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, - AttachmentsEnabled: true, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + AttachmentsEnabled: true, }, }, ) diff --git a/runtime/tests/checker/utils_test.go b/runtime/tests/checker/utils_test.go index 5e49dc708d..1c7a63804b 100644 --- a/runtime/tests/checker/utils_test.go +++ b/runtime/tests/checker/utils_test.go @@ -35,7 +35,9 @@ func ParseAndCheckWithPanic(t *testing.T, code string) (*sema.Checker, error) { code, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -54,7 +56,9 @@ func ParseAndCheckWithAny(t *testing.T, code string) (*sema.Checker, error) { code, ParseAndCheckOptions{ Config: &sema.Config{ - BaseTypeActivation: baseTypeActivation, + BaseTypeActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseTypeActivation + }, }, }, ) diff --git a/runtime/tests/interpreter/account_test.go b/runtime/tests/interpreter/account_test.go index 67768198a8..8b70cc8e05 100644 --- a/runtime/tests/interpreter/account_test.go +++ b/runtime/tests/interpreter/account_test.go @@ -89,14 +89,15 @@ func testAccount( accountValueDeclaration.Name = "account" valueDeclarations = append(valueDeclarations, accountValueDeclaration) - if checkerConfig.BaseValueActivation == nil { - checkerConfig.BaseValueActivation = sema.BaseValueActivation - } - baseValueActivation := sema.NewVariableActivation(checkerConfig.BaseValueActivation) + baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) for _, valueDeclaration := range valueDeclarations { baseValueActivation.DeclareValue(valueDeclaration) } - checkerConfig.BaseValueActivation = baseValueActivation + + require.Nil(t, checkerConfig.BaseValueActivationHandler) + checkerConfig.BaseValueActivationHandler = func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + } baseActivation := activations.NewActivation(nil, interpreter.BaseActivation) for _, valueDeclaration := range valueDeclarations { @@ -108,7 +109,9 @@ func testAccount( ParseCheckAndInterpretOptions{ CheckerConfig: &checkerConfig, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, ContractValueHandler: makeContractValueHandler(nil, nil, nil), AuthAccountHandler: func(address interpreter.AddressValue) interpreter.Value { return newTestAuthAccountValue(nil, address) @@ -3048,6 +3051,7 @@ func TestInterpretAccountIterationMutation(t *testing.T) { t.Run(fmt.Sprintf("with imported function call, continue: %t", continueAfterMutation), func(t *testing.T) { t.Parallel() + address := common.MustBytesToAddress([]byte{1}) addressValue := interpreter.AddressValue(address) @@ -3057,6 +3061,7 @@ func TestInterpretAccountIterationMutation(t *testing.T) { Value: newTestAuthAccountValue(nil, addressValue), Kind: common.DeclarationKindConstant, } + baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) baseValueActivation.DeclareValue(authAccountValueDeclaration) baseActivation := activations.NewActivation(nil, interpreter.BaseActivation) @@ -3074,7 +3079,9 @@ func TestInterpretAccountIterationMutation(t *testing.T) { Name: "foo", }, Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -3103,7 +3110,9 @@ func TestInterpretAccountIterationMutation(t *testing.T) { ), ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, LocationHandler: func( identifiers []ast.Identifier, location common.Location, @@ -3140,7 +3149,9 @@ func TestInterpretAccountIterationMutation(t *testing.T) { }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, ContractValueHandler: makeContractValueHandler(nil, nil, nil), ImportLocationHandler: func(inter *interpreter.Interpreter, location common.Location) interpreter.Import { require.IsType(t, common.AddressLocation{}, location) diff --git a/runtime/tests/interpreter/attachments_test.go b/runtime/tests/interpreter/attachments_test.go index 02da5ce876..617a36f402 100644 --- a/runtime/tests/interpreter/attachments_test.go +++ b/runtime/tests/interpreter/attachments_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/onflow/cadence/runtime/activations" + "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/interpreter" "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" @@ -1965,11 +1966,15 @@ func TestInterpretBuiltinCompositeAttachment(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, - AttachmentsEnabled: true, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + AttachmentsEnabled: true, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) diff --git a/runtime/tests/interpreter/composite_value_test.go b/runtime/tests/interpreter/composite_value_test.go index 228fa02e10..a3383537f5 100644 --- a/runtime/tests/interpreter/composite_value_test.go +++ b/runtime/tests/interpreter/composite_value_test.go @@ -145,8 +145,12 @@ func testCompositeValue(t *testing.T, code string) *interpreter.Interpreter { code, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, - BaseTypeActivation: baseTypeActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + BaseTypeActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseTypeActivation + }, CheckHandler: func(checker *sema.Checker, check func()) { if checker.Location == TestLocation { checker.Elaboration.SetCompositeType( @@ -158,8 +162,10 @@ func testCompositeValue(t *testing.T, code string) *interpreter.Interpreter { }, }, Config: &interpreter.Config{ - Storage: storage, - BaseActivation: baseActivation, + Storage: storage, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) diff --git a/runtime/tests/interpreter/condition_test.go b/runtime/tests/interpreter/condition_test.go index ac032ad166..294074f2ea 100644 --- a/runtime/tests/interpreter/condition_test.go +++ b/runtime/tests/interpreter/condition_test.go @@ -1174,10 +1174,14 @@ func TestInterpretFunctionWithPostConditionAndResourceResult(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) diff --git a/runtime/tests/interpreter/container_mutation_test.go b/runtime/tests/interpreter/container_mutation_test.go index af49b9e16e..00e5dbcf15 100644 --- a/runtime/tests/interpreter/container_mutation_test.go +++ b/runtime/tests/interpreter/container_mutation_test.go @@ -336,10 +336,14 @@ func TestArrayMutation(t *testing.T) { }`, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -475,10 +479,14 @@ func TestArrayMutation(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -726,10 +734,14 @@ func TestDictionaryMutation(t *testing.T) { }`, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -865,10 +877,14 @@ func TestDictionaryMutation(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) diff --git a/runtime/tests/interpreter/dynamic_casting_test.go b/runtime/tests/interpreter/dynamic_casting_test.go index ae820bfaf3..29af9ade52 100644 --- a/runtime/tests/interpreter/dynamic_casting_test.go +++ b/runtime/tests/interpreter/dynamic_casting_test.go @@ -3544,10 +3544,14 @@ func TestInterpretDynamicCastingCapability(t *testing.T) { options := ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, } diff --git a/runtime/tests/interpreter/equality_test.go b/runtime/tests/interpreter/equality_test.go index 091695f07d..95a4b5ae16 100644 --- a/runtime/tests/interpreter/equality_test.go +++ b/runtime/tests/interpreter/equality_test.go @@ -73,10 +73,14 @@ func TestInterpretEquality(t *testing.T) { `, ParseCheckAndInterpretOptions{ Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -127,10 +131,14 @@ func TestInterpretEquality(t *testing.T) { `, ParseCheckAndInterpretOptions{ Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) diff --git a/runtime/tests/interpreter/interpreter_test.go b/runtime/tests/interpreter/interpreter_test.go index 6f6157bab5..447b8cf04f 100644 --- a/runtime/tests/interpreter/interpreter_test.go +++ b/runtime/tests/interpreter/interpreter_test.go @@ -116,10 +116,14 @@ func parseCheckAndInterpretWithLogs( code, ParseCheckAndInterpretOptions{ Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, HandleCheckerError: nil, }, @@ -146,7 +150,9 @@ func parseCheckAndInterpretWithMemoryMetering( code, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, memoryGauge, @@ -1984,8 +1990,10 @@ func TestInterpretHostFunction(t *testing.T) { TestLocation, nil, &sema.Config{ - BaseValueActivation: baseValueActivation, - AccessCheckMode: sema.AccessCheckModeStrict, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + AccessCheckMode: sema.AccessCheckModeStrict, }, ) require.NoError(t, err) @@ -2002,8 +2010,10 @@ func TestInterpretHostFunction(t *testing.T) { interpreter.ProgramFromChecker(checker), checker.Location, &interpreter.Config{ - Storage: storage, - BaseActivation: baseActivation, + Storage: storage, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, ) require.NoError(t, err) @@ -2093,8 +2103,10 @@ func TestInterpretHostFunctionWithVariableArguments(t *testing.T) { TestLocation, nil, &sema.Config{ - BaseValueActivation: baseValueActivation, - AccessCheckMode: sema.AccessCheckModeStrict, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + AccessCheckMode: sema.AccessCheckModeStrict, }, ) require.NoError(t, err) @@ -2111,8 +2123,10 @@ func TestInterpretHostFunctionWithVariableArguments(t *testing.T) { interpreter.ProgramFromChecker(checker), checker.Location, &interpreter.Config{ - Storage: storage, - BaseActivation: baseActivation, + Storage: storage, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, ) require.NoError(t, err) @@ -2197,8 +2211,10 @@ func TestInterpretHostFunctionWithOptionalArguments(t *testing.T) { TestLocation, nil, &sema.Config{ - BaseValueActivation: baseValueActivation, - AccessCheckMode: sema.AccessCheckModeStrict, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + AccessCheckMode: sema.AccessCheckModeStrict, }, ) require.NoError(t, err) @@ -2215,8 +2231,10 @@ func TestInterpretHostFunctionWithOptionalArguments(t *testing.T) { interpreter.ProgramFromChecker(checker), checker.Location, &interpreter.Config{ - Storage: storage, - BaseActivation: baseActivation, + Storage: storage, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, ) require.NoError(t, err) @@ -4200,7 +4218,9 @@ func TestInterpretImportError(t *testing.T) { checker.ParseAndCheckOptions{ Location: location, Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, ImportHandler: func(_ *sema.Checker, importedLocation common.Location, _ ast.Range) (sema.Import, error) { switch importedLocation { case importedLocation1: @@ -4260,8 +4280,10 @@ func TestInterpretImportError(t *testing.T) { interpreter.ProgramFromChecker(mainChecker), mainChecker.Location, &interpreter.Config{ - Storage: storage, - BaseActivation: baseActivation, + Storage: storage, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, ImportLocationHandler: func(inter *interpreter.Interpreter, location common.Location) interpreter.Import { var importedChecker *sema.Checker switch location { @@ -5203,11 +5225,15 @@ func TestInterpretReferenceFailableDowncasting(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - Storage: storage, - BaseActivation: baseActivation, + Storage: storage, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -7564,8 +7590,12 @@ func TestInterpretEmitEventParameterTypes(t *testing.T) { inter, err := parseCheckAndInterpretWithOptions( t, code, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, - BaseTypeActivation: baseTypeActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + BaseTypeActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseTypeActivation + }, }, Config: &interpreter.Config{ Storage: storage, @@ -8373,10 +8403,14 @@ func TestInterpretOptionalChainingFieldReadAndNilCoalescing(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -8413,10 +8447,14 @@ func TestInterpretOptionalChainingFunctionCallAndNilCoalescing(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -8610,11 +8648,15 @@ func TestInterpretFungibleTokenContract(t *testing.T) { code, ParseCheckAndInterpretOptions{ Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, ContractValueHandler: makeContractValueHandler(nil, nil, nil), }, CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -9102,10 +9144,14 @@ func TestInterpretHexDecode(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -9448,10 +9494,14 @@ func TestInterpretResourceOwnerFieldUse(t *testing.T) { code, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, PublicAccountHandler: func(address interpreter.AddressValue) interpreter.Value { return newTestPublicAccountValue(nil, address) }, @@ -11724,10 +11774,14 @@ func TestInterpretNilCoalesceReference(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) diff --git a/runtime/tests/interpreter/invocation_test.go b/runtime/tests/interpreter/invocation_test.go index 58a45484fc..314ff4bb49 100644 --- a/runtime/tests/interpreter/invocation_test.go +++ b/runtime/tests/interpreter/invocation_test.go @@ -24,6 +24,7 @@ import ( "github.com/stretchr/testify/require" "github.com/onflow/cadence/runtime/activations" + "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/interpreter" "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" @@ -83,12 +84,16 @@ func TestInterpretSelfDeclaration(t *testing.T) { inter, err := parseCheckAndInterpretWithOptions(t, code, ParseCheckAndInterpretOptions{ Config: &interpreter.Config{ - Storage: newUnmeteredInMemoryStorage(), - BaseActivation: baseActivation, + Storage: newUnmeteredInMemoryStorage(), + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, - AccessCheckMode: sema.AccessCheckModeNotSpecifiedUnrestricted, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + AccessCheckMode: sema.AccessCheckModeNotSpecifiedUnrestricted, }, }) require.NoError(t, err) diff --git a/runtime/tests/interpreter/memory_metering_test.go b/runtime/tests/interpreter/memory_metering_test.go index b87abde5ea..b1d9912ba1 100644 --- a/runtime/tests/interpreter/memory_metering_test.go +++ b/runtime/tests/interpreter/memory_metering_test.go @@ -1066,10 +1066,14 @@ func TestInterpretHostFunctionMetering(t *testing.T) { script, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, meter, @@ -1115,10 +1119,14 @@ func TestInterpretHostFunctionMetering(t *testing.T) { script, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, meter, @@ -1169,10 +1177,14 @@ func TestInterpretHostFunctionMetering(t *testing.T) { script, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, meter, @@ -8766,10 +8778,14 @@ func TestInterpretValueStringConversion(t *testing.T) { inter, err := parseCheckAndInterpretWithOptionsAndMemoryMetering(t, script, ParseCheckAndInterpretOptions{ Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, meter, @@ -9128,10 +9144,14 @@ func TestInterpretStaticTypeStringConversion(t *testing.T) { inter, err := parseCheckAndInterpretWithOptionsAndMemoryMetering(t, script, ParseCheckAndInterpretOptions{ Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, meter, diff --git a/runtime/tests/interpreter/metatype_test.go b/runtime/tests/interpreter/metatype_test.go index 474dbfa8cb..296f9dbffc 100644 --- a/runtime/tests/interpreter/metatype_test.go +++ b/runtime/tests/interpreter/metatype_test.go @@ -142,10 +142,14 @@ func TestInterpretMetaTypeEquality(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -198,10 +202,14 @@ func TestInterpretMetaTypeEquality(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -287,10 +295,14 @@ func TestInterpretMetaTypeIdentifier(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -440,10 +452,14 @@ func TestInterpretIsInstance(t *testing.T) { t.Run(testCase.name, func(t *testing.T) { inter, err := parseCheckAndInterpretWithOptions(t, testCase.code, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }) require.NoError(t, err) @@ -580,10 +596,14 @@ func TestInterpretMetaTypeIsSubtype(t *testing.T) { t.Run(testCase.name, func(t *testing.T) { inter, err := parseCheckAndInterpretWithOptions(t, testCase.code, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }) require.NoError(t, err) @@ -793,11 +813,15 @@ func TestInterpretGetType(t *testing.T) { testCase.code, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - Storage: storage, - BaseActivation: baseActivation, + Storage: storage, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) diff --git a/runtime/tests/interpreter/transfer_test.go b/runtime/tests/interpreter/transfer_test.go index df28e93029..f447d4bf5c 100644 --- a/runtime/tests/interpreter/transfer_test.go +++ b/runtime/tests/interpreter/transfer_test.go @@ -76,11 +76,17 @@ func TestInterpretTransferCheck(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseTypeActivation: baseTypeActivation, - BaseValueActivation: baseValueActivation, + BaseTypeActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseTypeActivation + }, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) diff --git a/tools/analysis/programs.go b/tools/analysis/programs.go index 99ebd821e9..4985cedd01 100644 --- a/tools/analysis/programs.go +++ b/tools/analysis/programs.go @@ -109,8 +109,10 @@ func (programs Programs) check( location, nil, &sema.Config{ - BaseValueActivation: baseValueActivation, - AccessCheckMode: sema.AccessCheckModeStrict, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + AccessCheckMode: sema.AccessCheckModeStrict, LocationHandler: sema.AddressLocationHandlerFunc( config.ResolveAddressContractNames, ),