From a85d53cf62e381c6c59369d1a5fac974f7e81c59 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Tue, 2 Apr 2024 16:32:23 -0700 Subject: [PATCH 1/7] Add InternalEVM contract to stdlib --- languageserver/go.mod | 2 +- languageserver/server/stdlib.go | 29 +++++++++++++++++++++++++++-- languageserver/test/index.test.ts | 14 ++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/languageserver/go.mod b/languageserver/go.mod index 7a2ac5dc..ae07cc16 100644 --- a/languageserver/go.mod +++ b/languageserver/go.mod @@ -10,6 +10,7 @@ require ( github.com/onflow/cadence v1.0.0-preview.18 github.com/onflow/cadence-tools/lint v1.0.0-preview.12 github.com/onflow/cadence-tools/test v1.0.0-preview.12 + github.com/onflow/flow-go v0.34.0-crescendo-preview.8.0.20240328003708-11040f76d0cd github.com/onflow/flow-go-sdk v1.0.0-preview.16 github.com/onflow/flowkit/v2 v2.0.0-stable-cadence-alpha.12 github.com/sourcegraph/jsonrpc2 v0.1.0 @@ -140,7 +141,6 @@ require ( github.com/onflow/flow-emulator v1.0.0-preview.15 // indirect github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240327162334-bd133114f87a // indirect github.com/onflow/flow-ft/lib/go/templates v0.7.1-0.20240327162334-bd133114f87a // indirect - github.com/onflow/flow-go v0.34.0-crescendo-preview.8.0.20240328003708-11040f76d0cd // indirect github.com/onflow/flow-nft/lib/go/contracts v1.1.1-0.20240326155818-c01c72c091c0 // indirect github.com/onflow/flow-nft/lib/go/templates v0.0.0-20240326155818-c01c72c091c0 // indirect github.com/onflow/flow/protobuf/go/flow v0.3.7 // indirect diff --git a/languageserver/server/stdlib.go b/languageserver/server/stdlib.go index 41a30b2c..b868eace 100644 --- a/languageserver/server/stdlib.go +++ b/languageserver/server/stdlib.go @@ -24,6 +24,7 @@ import ( "github.com/onflow/cadence/runtime/interpreter" "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" + evmstdlib "github.com/onflow/flow-go/fvm/evm/stdlib" ) type standardLibrary struct { @@ -287,7 +288,12 @@ func (standardLibrary) IsContractBeingAdded(_ common.AddressLocation) bool { func newStandardLibrary() (result standardLibrary) { result.baseValueActivation = sema.NewVariableActivation(sema.BaseValueActivation) - for _, valueDeclaration := range stdlib.DefaultStandardLibraryValues(result) { + + values := []stdlib.StandardLibraryValue{} + values = append(values, stdlib.DefaultStandardLibraryValues(result)...) + values = append(values, fvmStandardLibraryValues()...) + + for _, valueDeclaration := range values { result.baseValueActivation.DeclareValue(valueDeclaration) } return @@ -295,8 +301,27 @@ func newStandardLibrary() (result standardLibrary) { func newScriptStandardLibrary() (result standardLibrary) { result.baseValueActivation = sema.NewVariableActivation(sema.BaseValueActivation) - for _, declaration := range stdlib.DefaultScriptStandardLibraryValues(result) { + + values := []stdlib.StandardLibraryValue{} + values = append(values, stdlib.DefaultScriptStandardLibraryValues(result)...) + values = append(values, fvmStandardLibraryValues()...) + + for _, declaration := range values { result.baseValueActivation.DeclareValue(declaration) } return } + +// fvmStandardLibraryValues returns the standard library values which are provided by the FVM +// these are not part of the Cadence standard library +func fvmStandardLibraryValues() []stdlib.StandardLibraryValue { + return []stdlib.StandardLibraryValue{ + // InternalEVM contract + { + Name: evmstdlib.InternalEVMContractName, + Type: evmstdlib.InternalEVMContractType, + Value: evmstdlib.NewInternalEVMContractValue(nil, nil, common.AddressLocation{}), + Kind: common.DeclarationKindContract, + }, + } +} diff --git a/languageserver/test/index.test.ts b/languageserver/test/index.test.ts index b73f5c32..3789d8bb 100644 --- a/languageserver/test/index.test.ts +++ b/languageserver/test/index.test.ts @@ -308,6 +308,20 @@ describe("diagnostics", () => { ) ) + test("InternalEVM contract exists", async() => + testCode( + ` + access(all) + fun main() { + // Checks that the InternalEVM contract exists + // Also that it has the correct value (i.e. the run function exists) + log(InternalEVM.run) + } + `, + [] + ) + ) + type TestDoc = { name: string code: string From 5876ad8843190f3ed62f260c688f01ffd25672f8 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Wed, 3 Apr 2024 08:42:52 -0700 Subject: [PATCH 2/7] move EVM contract to flow integration --- languageserver/integration/integration.go | 1 + languageserver/integration/stdlib.go | 21 +++++++++++++++++++++ languageserver/server/server.go | 14 ++++++++++++++ languageserver/server/stdlib.go | 23 ++++------------------- 4 files changed, 40 insertions(+), 19 deletions(-) create mode 100644 languageserver/integration/stdlib.go diff --git a/languageserver/integration/integration.go b/languageserver/integration/integration.go index 683c12dc..583f1fe4 100644 --- a/languageserver/integration/integration.go +++ b/languageserver/integration/integration.go @@ -52,6 +52,7 @@ func NewFlowIntegration(s *server.Server, enableFlowClient bool) (*FlowIntegrati server.WithDiagnosticProvider(diagnostics), server.WithStringImportResolver(resolve.stringImport), server.WithInitializationOptionsHandler(integration.initialize), + server.WithExtendedStandardLibraryValues(fvmStandardLibraryValues()...), } if enableFlowClient { diff --git a/languageserver/integration/stdlib.go b/languageserver/integration/stdlib.go new file mode 100644 index 00000000..22b3aacc --- /dev/null +++ b/languageserver/integration/stdlib.go @@ -0,0 +1,21 @@ +package integration + +import ( + "github.com/onflow/cadence/runtime/common" + "github.com/onflow/cadence/runtime/stdlib" + evmstdlib "github.com/onflow/flow-go/fvm/evm/stdlib" +) + +// fvmStandardLibraryValues returns the standard library values which are provided by the FVM +// these are not part of the Cadence standard library +func fvmStandardLibraryValues() []stdlib.StandardLibraryValue { + return []stdlib.StandardLibraryValue{ + // InternalEVM contract + { + Name: evmstdlib.InternalEVMContractName, + Type: evmstdlib.InternalEVMContractType, + Value: evmstdlib.NewInternalEVMContractValue(nil, nil, common.AddressLocation{}), + Kind: common.DeclarationKindContract, + }, + } +} diff --git a/languageserver/server/server.go b/languageserver/server/server.go index 927db431..e4531cfc 100644 --- a/languageserver/server/server.go +++ b/languageserver/server/server.go @@ -184,6 +184,8 @@ type Server struct { // initializationOptionsHandlers are the functions that are used to handle initialization options sent by the client initializationOptionsHandlers []InitializationOptionsHandler accessCheckMode sema.AccessCheckMode + // extendedStandardLibraryValues are the standard library values that are provided in addition to the default standard library + extendedStandardLibraryValues []stdlib.StandardLibraryValue // reportCrashes decides when the crash is detected should it be reported reportCrashes bool // checkerStandardConfig is a config used to check contracts and transactions @@ -280,6 +282,18 @@ func WithMemberAccountAccessHandler(handler sema.MemberAccountAccessHandlerFunc) } } +// WithStandardLibraryValues returns a server option that adds the given function +// as a function that is used to resolve standard library values (in addition to the default standard library) +// +// This is used to provide parts of the standard library that are present in an environment, +// but are not native to the language. +func WithExtendedStandardLibraryValues(values ...stdlib.StandardLibraryValue) Option { + return func(server *Server) error { + server.extendedStandardLibraryValues = append(server.extendedStandardLibraryValues, values...) + return nil + } +} + const GetEntryPointParametersCommand = "cadence.server.getEntryPointParameters" const GetContractInitializerParametersCommand = "cadence.server.getContractInitializerParameters" const ParseEntryPointArgumentsCommand = "cadence.server.parseEntryPointArguments" diff --git a/languageserver/server/stdlib.go b/languageserver/server/stdlib.go index b868eace..2031914b 100644 --- a/languageserver/server/stdlib.go +++ b/languageserver/server/stdlib.go @@ -24,7 +24,6 @@ import ( "github.com/onflow/cadence/runtime/interpreter" "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" - evmstdlib "github.com/onflow/flow-go/fvm/evm/stdlib" ) type standardLibrary struct { @@ -286,12 +285,12 @@ func (standardLibrary) IsContractBeingAdded(_ common.AddressLocation) bool { panic(errors.NewUnreachableError()) } -func newStandardLibrary() (result standardLibrary) { +func newStandardLibrary(additionalValues ...stdlib.StandardLibraryValue) (result standardLibrary) { result.baseValueActivation = sema.NewVariableActivation(sema.BaseValueActivation) values := []stdlib.StandardLibraryValue{} values = append(values, stdlib.DefaultStandardLibraryValues(result)...) - values = append(values, fvmStandardLibraryValues()...) + values = append(values, additionalValues...) for _, valueDeclaration := range values { result.baseValueActivation.DeclareValue(valueDeclaration) @@ -299,29 +298,15 @@ func newStandardLibrary() (result standardLibrary) { return } -func newScriptStandardLibrary() (result standardLibrary) { +func newScriptStandardLibrary(additionalValues ...stdlib.StandardLibraryValue) (result standardLibrary) { result.baseValueActivation = sema.NewVariableActivation(sema.BaseValueActivation) values := []stdlib.StandardLibraryValue{} values = append(values, stdlib.DefaultScriptStandardLibraryValues(result)...) - values = append(values, fvmStandardLibraryValues()...) + values = append(values, additionalValues...) for _, declaration := range values { result.baseValueActivation.DeclareValue(declaration) } return } - -// fvmStandardLibraryValues returns the standard library values which are provided by the FVM -// these are not part of the Cadence standard library -func fvmStandardLibraryValues() []stdlib.StandardLibraryValue { - return []stdlib.StandardLibraryValue{ - // InternalEVM contract - { - Name: evmstdlib.InternalEVMContractName, - Type: evmstdlib.InternalEVMContractType, - Value: evmstdlib.NewInternalEVMContractValue(nil, nil, common.AddressLocation{}), - Kind: common.DeclarationKindContract, - }, - } -} From cdb25b9f460864dcaf3e714b02d4ca36b6a132bb Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Wed, 3 Apr 2024 11:19:08 -0700 Subject: [PATCH 3/7] fix updating checkers --- languageserver/server/server.go | 23 ++++++++++++++++------- languageserver/server/stdlib.go | 18 ++++-------------- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/languageserver/server/server.go b/languageserver/server/server.go index e4531cfc..6f2ca2f2 100644 --- a/languageserver/server/server.go +++ b/languageserver/server/server.go @@ -184,14 +184,16 @@ type Server struct { // initializationOptionsHandlers are the functions that are used to handle initialization options sent by the client initializationOptionsHandlers []InitializationOptionsHandler accessCheckMode sema.AccessCheckMode - // extendedStandardLibraryValues are the standard library values that are provided in addition to the default standard library - extendedStandardLibraryValues []stdlib.StandardLibraryValue // reportCrashes decides when the crash is detected should it be reported reportCrashes bool // checkerStandardConfig is a config used to check contracts and transactions checkerStandardConfig *sema.Config // checkerScriptConfig is a config used to check scripts checkerScriptConfig *sema.Config + // standardLibrary is the default standard library + standardLibrary *standardLibrary + // scriptStandardLibrary is the standard library for scripts + scriptStandardLibrary *standardLibrary } type Option func(*Server) error @@ -285,11 +287,14 @@ func WithMemberAccountAccessHandler(handler sema.MemberAccountAccessHandlerFunc) // WithStandardLibraryValues returns a server option that adds the given function // as a function that is used to resolve standard library values (in addition to the default standard library) // -// This is used to provide parts of the standard library that are present in an environment, +// This is used to provide parts of the standard library that are present in some given environment // but are not native to the language. func WithExtendedStandardLibraryValues(values ...stdlib.StandardLibraryValue) Option { return func(server *Server) error { - server.extendedStandardLibraryValues = append(server.extendedStandardLibraryValues, values...) + for _, value := range values { + server.standardLibrary.baseValueActivation.DeclareValue(value) + server.scriptStandardLibrary.baseValueActivation.DeclareValue(value) + } return nil } } @@ -323,15 +328,19 @@ func NewServer() (*Server, error) { } } + // create standard libraries + server.standardLibrary = newStandardLibrary() + server.scriptStandardLibrary = newScriptStandardLibrary() + // create checker configurations - server.checkerStandardConfig = newCheckerConfig(server, newStandardLibrary()) - server.checkerScriptConfig = newCheckerConfig(server, newScriptStandardLibrary()) + server.checkerStandardConfig = newCheckerConfig(server, server.standardLibrary) + server.checkerScriptConfig = newCheckerConfig(server, server.scriptStandardLibrary) return server, nil } // newCheckerConfig creates a checker config based on the standard library provided set to base value activations. -func newCheckerConfig(s *Server, lib standardLibrary) *sema.Config { +func newCheckerConfig(s *Server, lib *standardLibrary) *sema.Config { return &sema.Config{ BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { return lib.baseValueActivation diff --git a/languageserver/server/stdlib.go b/languageserver/server/stdlib.go index 2031914b..2586dd98 100644 --- a/languageserver/server/stdlib.go +++ b/languageserver/server/stdlib.go @@ -285,27 +285,17 @@ func (standardLibrary) IsContractBeingAdded(_ common.AddressLocation) bool { panic(errors.NewUnreachableError()) } -func newStandardLibrary(additionalValues ...stdlib.StandardLibraryValue) (result standardLibrary) { +func newStandardLibrary() (result *standardLibrary) { result.baseValueActivation = sema.NewVariableActivation(sema.BaseValueActivation) - - values := []stdlib.StandardLibraryValue{} - values = append(values, stdlib.DefaultStandardLibraryValues(result)...) - values = append(values, additionalValues...) - - for _, valueDeclaration := range values { + for _, valueDeclaration := range stdlib.DefaultStandardLibraryValues(result) { result.baseValueActivation.DeclareValue(valueDeclaration) } return } -func newScriptStandardLibrary(additionalValues ...stdlib.StandardLibraryValue) (result standardLibrary) { +func newScriptStandardLibrary() (result *standardLibrary) { result.baseValueActivation = sema.NewVariableActivation(sema.BaseValueActivation) - - values := []stdlib.StandardLibraryValue{} - values = append(values, stdlib.DefaultScriptStandardLibraryValues(result)...) - values = append(values, additionalValues...) - - for _, declaration := range values { + for _, declaration := range stdlib.DefaultScriptStandardLibraryValues(result) { result.baseValueActivation.DeclareValue(declaration) } return From 107952125c9494a2b00c7615eb5564ca75a79d50 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Wed, 3 Apr 2024 13:24:11 -0700 Subject: [PATCH 4/7] fix nil pointer --- languageserver/cmd/languageserver/main_wasm.go | 2 ++ languageserver/integration/integration.go | 2 +- languageserver/integration/stdlib.go | 4 ++-- languageserver/server/stdlib.go | 10 ++++++---- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/languageserver/cmd/languageserver/main_wasm.go b/languageserver/cmd/languageserver/main_wasm.go index 19b445b6..8b5e65e0 100644 --- a/languageserver/cmd/languageserver/main_wasm.go +++ b/languageserver/cmd/languageserver/main_wasm.go @@ -30,6 +30,7 @@ import ( "github.com/onflow/cadence/runtime/common" + "github.com/onflow/cadence-tools/languageserver/integration" "github.com/onflow/cadence-tools/languageserver/server" ) @@ -193,6 +194,7 @@ func start(id int) { err = languageServer.SetOptions( server.WithAddressImportResolver(addressImportResolver), server.WithStringImportResolver(stringImportResolver), + server.WithExtendedStandardLibraryValues(integration.FVMStandardLibraryValues), ) if err != nil { panic(err) diff --git a/languageserver/integration/integration.go b/languageserver/integration/integration.go index 583f1fe4..a31fd6d0 100644 --- a/languageserver/integration/integration.go +++ b/languageserver/integration/integration.go @@ -52,7 +52,7 @@ func NewFlowIntegration(s *server.Server, enableFlowClient bool) (*FlowIntegrati server.WithDiagnosticProvider(diagnostics), server.WithStringImportResolver(resolve.stringImport), server.WithInitializationOptionsHandler(integration.initialize), - server.WithExtendedStandardLibraryValues(fvmStandardLibraryValues()...), + server.WithExtendedStandardLibraryValues(FVMStandardLibraryValues()...), } if enableFlowClient { diff --git a/languageserver/integration/stdlib.go b/languageserver/integration/stdlib.go index 22b3aacc..dcdc3d51 100644 --- a/languageserver/integration/stdlib.go +++ b/languageserver/integration/stdlib.go @@ -6,9 +6,9 @@ import ( evmstdlib "github.com/onflow/flow-go/fvm/evm/stdlib" ) -// fvmStandardLibraryValues returns the standard library values which are provided by the FVM +// FVMtandardLibraryValues returns the standard library values which are provided by the FVM // these are not part of the Cadence standard library -func fvmStandardLibraryValues() []stdlib.StandardLibraryValue { +func FVMStandardLibraryValues() []stdlib.StandardLibraryValue { return []stdlib.StandardLibraryValue{ // InternalEVM contract { diff --git a/languageserver/server/stdlib.go b/languageserver/server/stdlib.go index 2586dd98..26056ce2 100644 --- a/languageserver/server/stdlib.go +++ b/languageserver/server/stdlib.go @@ -285,18 +285,20 @@ func (standardLibrary) IsContractBeingAdded(_ common.AddressLocation) bool { panic(errors.NewUnreachableError()) } -func newStandardLibrary() (result *standardLibrary) { +func newStandardLibrary() *standardLibrary { + result := &standardLibrary{} result.baseValueActivation = sema.NewVariableActivation(sema.BaseValueActivation) for _, valueDeclaration := range stdlib.DefaultStandardLibraryValues(result) { result.baseValueActivation.DeclareValue(valueDeclaration) } - return + return result } -func newScriptStandardLibrary() (result *standardLibrary) { +func newScriptStandardLibrary() *standardLibrary { + result := &standardLibrary{} result.baseValueActivation = sema.NewVariableActivation(sema.BaseValueActivation) for _, declaration := range stdlib.DefaultScriptStandardLibraryValues(result) { result.baseValueActivation.DeclareValue(declaration) } - return + return result } From 828a178b267d4a4766b1643142d25ff93a4c691f Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Wed, 3 Apr 2024 13:26:33 -0700 Subject: [PATCH 5/7] fix lint --- languageserver/integration/stdlib.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/languageserver/integration/stdlib.go b/languageserver/integration/stdlib.go index dcdc3d51..21c91ddd 100644 --- a/languageserver/integration/stdlib.go +++ b/languageserver/integration/stdlib.go @@ -1,3 +1,21 @@ +/* + * Cadence - The resource-oriented smart contract programming language + * + * Copyright 2019-2022 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 integration import ( From 86b799c1d4fe45cdd44e8c94b371eb57a1bdfb7d Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Wed, 3 Apr 2024 13:45:29 -0700 Subject: [PATCH 6/7] remove wasm --- languageserver/cmd/languageserver/main_wasm.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/languageserver/cmd/languageserver/main_wasm.go b/languageserver/cmd/languageserver/main_wasm.go index 8b5e65e0..19b445b6 100644 --- a/languageserver/cmd/languageserver/main_wasm.go +++ b/languageserver/cmd/languageserver/main_wasm.go @@ -30,7 +30,6 @@ import ( "github.com/onflow/cadence/runtime/common" - "github.com/onflow/cadence-tools/languageserver/integration" "github.com/onflow/cadence-tools/languageserver/server" ) @@ -194,7 +193,6 @@ func start(id int) { err = languageServer.SetOptions( server.WithAddressImportResolver(addressImportResolver), server.WithStringImportResolver(stringImportResolver), - server.WithExtendedStandardLibraryValues(integration.FVMStandardLibraryValues), ) if err != nil { panic(err) From 5189a5d4e2c9b86771bc16349a0c6e83cd78ed62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Wed, 7 Aug 2024 18:35:55 -0700 Subject: [PATCH 7/7] go mod tidy --- languageserver/go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languageserver/go.mod b/languageserver/go.mod index 3a66d248..6a593982 100644 --- a/languageserver/go.mod +++ b/languageserver/go.mod @@ -10,6 +10,7 @@ require ( github.com/onflow/cadence v1.0.0-preview.39 github.com/onflow/cadence-tools/lint v1.0.0-preview.35 github.com/onflow/cadence-tools/test v1.0.0-preview.35 + github.com/onflow/flow-go v0.36.4-0.20240724205438-14f9fddeda2b github.com/onflow/flow-go-sdk v1.0.0-preview.42 github.com/onflow/flowkit/v2 v2.0.0-stable-cadence-alpha.27 github.com/sourcegraph/jsonrpc2 v0.1.0 @@ -155,7 +156,6 @@ require ( github.com/onflow/flow-emulator v1.0.0-preview.36 // indirect github.com/onflow/flow-ft/lib/go/contracts v1.0.0 // indirect github.com/onflow/flow-ft/lib/go/templates v1.0.0 // indirect - github.com/onflow/flow-go v0.36.4-0.20240724205438-14f9fddeda2b // indirect github.com/onflow/flow-nft/lib/go/contracts v1.2.1 // indirect github.com/onflow/flow-nft/lib/go/templates v1.2.0 // indirect github.com/onflow/flow/protobuf/go/flow v0.4.5 // indirect