@@ -31,14 +31,15 @@ use super::analysis::{self, ContractAnalysis};
31
31
#[ cfg( feature = "clarity-wasm" ) ]
32
32
use super :: clarity_wasm:: call_function;
33
33
use super :: EvalHook ;
34
+ use crate :: vm:: analysis:: AnalysisDatabase ;
34
35
use crate :: vm:: ast:: { ASTRules , ContractAST } ;
35
36
use crate :: vm:: callables:: { DefinedFunction , FunctionIdentifier } ;
36
37
use crate :: vm:: contracts:: Contract ;
37
38
use crate :: vm:: costs:: cost_functions:: ClarityCostFunction ;
38
39
use crate :: vm:: costs:: { runtime_cost, CostErrors , CostTracker , ExecutionCost , LimitedCostTracker } ;
39
40
use crate :: vm:: database:: {
40
41
ClarityDatabase , DataMapMetadata , DataVariableMetadata , FungibleTokenMetadata ,
41
- NonFungibleTokenMetadata ,
42
+ MemoryBackingStore , NonFungibleTokenMetadata ,
42
43
} ;
43
44
use crate :: vm:: errors:: {
44
45
CheckErrors , InterpreterError , InterpreterResult as Result , RuntimeErrorType ,
@@ -658,13 +659,56 @@ impl<'a> OwnedEnvironment<'a> {
658
659
contract_content : & str ,
659
660
sponsor : Option < PrincipalData > ,
660
661
ast_rules : ASTRules ,
662
+ ) -> Result < ( ( ) , AssetMap , Vec < StacksTransactionEvent > ) > {
663
+ let mut store = MemoryBackingStore :: new ( ) ;
664
+ let mut analysis_db = store. as_analysis_db ( ) ;
665
+ analysis_db. begin ( ) ;
666
+
667
+ self . initialize_contract_with_db (
668
+ contract_identifier,
669
+ contract_content,
670
+ sponsor,
671
+ ast_rules,
672
+ & mut analysis_db,
673
+ )
674
+ }
675
+
676
+ /// Initializes a Clarity smart contract with a custom analysis database within a transaction context.
677
+ ///
678
+ /// This function should only be used for testing.
679
+ ///
680
+ /// This function creates a complete transaction environment to initialize a Clarity smart contract
681
+ /// using a provided memory-backed database for analysis data. It executes the contract initialization
682
+ /// within a proper execution context.
683
+ ///
684
+ /// # Arguments
685
+ ///
686
+ /// * `contract_identifier` - Unique identifier for the contract (principal + contract name)
687
+ /// * `contract_content` - The raw Clarity source code as a string
688
+ /// * `sponsor` - Optional sponsor principal for transaction fees (if `None`, sender pays)
689
+ /// * `ast_rules` - Parsing rules to apply during AST construction (e.g., `ASTRules::PrecheckSize`)
690
+ /// * `analysis_db` - Mutable reference to a database for analysis data
691
+ ///
692
+ #[ cfg( any( test, feature = "testing" ) ) ]
693
+ pub fn initialize_contract_with_db (
694
+ & mut self ,
695
+ contract_identifier : QualifiedContractIdentifier ,
696
+ contract_content : & str ,
697
+ sponsor : Option < PrincipalData > ,
698
+ ast_rules : ASTRules ,
699
+ analysis_db : & mut AnalysisDatabase ,
661
700
) -> Result < ( ( ) , AssetMap , Vec < StacksTransactionEvent > ) > {
662
701
self . execute_in_env (
663
702
contract_identifier. issuer . clone ( ) . into ( ) ,
664
703
sponsor,
665
704
None ,
666
705
|exec_env| {
667
- exec_env. initialize_contract ( contract_identifier, contract_content, ast_rules)
706
+ exec_env. initialize_contract_with_db (
707
+ contract_identifier,
708
+ contract_content,
709
+ ast_rules,
710
+ analysis_db,
711
+ )
668
712
} ,
669
713
)
670
714
}
@@ -1341,8 +1385,46 @@ impl<'a, 'b> Environment<'a, 'b> {
1341
1385
contract_content : & str ,
1342
1386
ast_rules : ASTRules ,
1343
1387
) -> Result < ( ) > {
1344
- use super :: database:: MemoryBackingStore ;
1388
+ let mut store = MemoryBackingStore :: new ( ) ;
1389
+ let mut analysis_db = store. as_analysis_db ( ) ;
1390
+ analysis_db. begin ( ) ;
1391
+
1392
+ self . initialize_contract_with_db (
1393
+ contract_identifier,
1394
+ contract_content,
1395
+ ast_rules,
1396
+ & mut analysis_db,
1397
+ )
1398
+ }
1345
1399
1400
+ /// Initializes a Clarity smart contract with a custom analysis database.
1401
+ ///
1402
+ /// This function should only be used for testing.
1403
+ ///
1404
+ /// This function parses and analyzes a Clarity smart contract using
1405
+ /// a provided database for analysis data. It's primarily used for testing
1406
+ /// scenarios where you need control over the backing storage.
1407
+ ///
1408
+ /// # Arguments
1409
+ ///
1410
+ /// * `contract_identifier` - Unique identifier for the contract (principal + name)
1411
+ /// * `contract_content` - The raw Clarity source code as a string
1412
+ /// * `ast_rules` - Parsing rules to apply during AST construction
1413
+ /// * `analysis_db` - Mutable reference to a database for analysis data
1414
+ ///
1415
+ /// # Returns
1416
+ ///
1417
+ /// * `Ok(())` - Contract successfully initialized
1418
+ /// * `Err(Error)` - Initialization failed due to parsing or analysis
1419
+ ///
1420
+ #[ cfg( feature = "rusqlite" ) ]
1421
+ pub fn initialize_contract_with_db (
1422
+ & mut self ,
1423
+ contract_identifier : QualifiedContractIdentifier ,
1424
+ contract_content : & str ,
1425
+ ast_rules : ASTRules ,
1426
+ analysis_db : & mut AnalysisDatabase ,
1427
+ ) -> Result < ( ) > {
1346
1428
let clarity_version = self . contract_context . clarity_version ;
1347
1429
1348
1430
let mut contract_ast = ast:: build_ast_with_rules (
@@ -1354,12 +1436,11 @@ impl<'a, 'b> Environment<'a, 'b> {
1354
1436
ast_rules,
1355
1437
) ?;
1356
1438
1357
- let mut store = MemoryBackingStore :: new ( ) ;
1358
1439
let contract_analysis = analysis:: run_analysis (
1359
1440
& contract_identifier,
1360
1441
& contract_ast. expressions ,
1361
- & mut store . as_analysis_db ( ) ,
1362
- false ,
1442
+ analysis_db ,
1443
+ true ,
1363
1444
LimitedCostTracker :: Free ,
1364
1445
self . global_context . epoch_id ,
1365
1446
clarity_version,
0 commit comments