From 64a60b51f7e958a7c273f553c868b66c68390c2a Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Tue, 23 Dec 2025 14:54:54 -0800 Subject: [PATCH 1/2] Add legacy `Crypto` identifier to linter --- internal/cadence/linter.go | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/internal/cadence/linter.go b/internal/cadence/linter.go index a1603e94b..fa2fb2677 100644 --- a/internal/cadence/linter.go +++ b/internal/cadence/linter.go @@ -35,6 +35,7 @@ import ( "github.com/onflow/cadence/sema" "github.com/onflow/cadence/stdlib" "github.com/onflow/cadence/tools/analysis" + "github.com/onflow/flow-core-contracts/lib/go/contracts" "github.com/onflow/flowkit/v2" "golang.org/x/exp/maps" ) @@ -319,6 +320,41 @@ func (l *linter) handleImport( return sema.ElaborationImport{ Elaboration: helpersChecker.Elaboration, }, nil + case stdlib.CryptoContractLocation: + cryptoChecker, ok := l.checkers[stdlib.CryptoContractLocation.String()] + if !ok { + cryptoCode := contracts.Crypto() + cryptoProgram, err := parser.ParseProgram(nil, cryptoCode, parser.Config{}) + if err != nil { + return nil, err + } + if cryptoProgram == nil { + return nil, &sema.CheckerError{ + Errors: []error{fmt.Errorf("cannot parse Crypto contract")}, + } + } + + cryptoChecker, err = sema.NewChecker( + cryptoProgram, + stdlib.CryptoContractLocation, + nil, + l.checkerStandardConfig, + ) + if err != nil { + return nil, err + } + + err = cryptoChecker.Check() + if err != nil { + return nil, err + } + + l.checkers[stdlib.CryptoContractLocation.String()] = cryptoChecker + } + + return sema.ElaborationImport{ + Elaboration: cryptoChecker.Elaboration, + }, nil default: // Normalize relative path imports to absolute paths if util.IsPathLocation(importedLocation) { From 3b8aa3cb1dbd209a7b3cd81f4409a682a7866ee4 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Tue, 23 Dec 2025 15:34:43 -0800 Subject: [PATCH 2/2] add test --- internal/cadence/lint_test.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/internal/cadence/lint_test.go b/internal/cadence/lint_test.go index 44729d243..b39c932fa 100644 --- a/internal/cadence/lint_test.go +++ b/internal/cadence/lint_test.go @@ -300,6 +300,28 @@ func Test_Lint(t *testing.T) { ) }) + t.Run("resolves stdlib imports Crypto", func(t *testing.T) { + t.Parallel() + + state := setupMockState(t) + + results, err := lintFiles(state, "StdlibImportsCrypto.cdc") + require.NoError(t, err) + + require.Equal(t, + &lintResult{ + Results: []fileResult{ + { + FilePath: "StdlibImportsCrypto.cdc", + Diagnostics: []analysis.Diagnostic{}, + }, + }, + exitCode: 0, + }, + results, + ) + }) + t.Run("resolves nested imports when contract imported by name", func(t *testing.T) { t.Parallel() @@ -392,6 +414,15 @@ func setupMockState(t *testing.T) *flowkit.State { let foo = getAuthAccount<&Account>(0x01) log(RLP.getType()) }`), 0644) + _ = afero.WriteFile(mockFs, "StdlibImportsCrypto.cdc", []byte(` + import Crypto + + access(all) contract CryptoImportTest { + access(all) fun test(): Void { + let _ = Crypto.hash([1, 2, 3], algorithm: HashAlgorithm.SHA3_256) + } + } + `), 0644) // Regression test files for nested import bug _ = afero.WriteFile(mockFs, "Helper.cdc", []byte(`