slither.vyper_parsing.vyper_compilation_unit

 1from typing import Dict
 2import os
 3import re
 4from dataclasses import dataclass, field
 5from slither.core.declarations import Contract
 6from slither.core.compilation_unit import SlitherCompilationUnit
 7from slither.vyper_parsing.declarations.contract import ContractVyper
 8from slither.analyses.data_dependency.data_dependency import compute_dependency
 9from slither.vyper_parsing.ast.types import Module
10from slither.exceptions import SlitherException
11
12
13@dataclass
14class VyperCompilationUnit:
15    _compilation_unit: SlitherCompilationUnit
16    _parsed: bool = False
17    _analyzed: bool = False
18    _underlying_contract_to_parser: Dict[Contract, ContractVyper] = field(default_factory=dict)
19    _contracts_by_id: Dict[int, Contract] = field(default_factory=dict)
20
21    def parse_module(self, data: Module, filename: str):
22
23        sourceUnit_candidates = re.findall("[0-9]*:[0-9]*:([0-9]*)", data.src)
24        assert len(sourceUnit_candidates) == 1, "Source unit not found"
25        sourceUnit = int(sourceUnit_candidates[0])
26
27        self._compilation_unit.source_units[sourceUnit] = filename
28        if os.path.isfile(filename) and filename not in self._compilation_unit.core.source_code:
29            self._compilation_unit.core.add_source_code(filename)
30
31        scope = self._compilation_unit.get_scope(filename)
32        contract = Contract(self._compilation_unit, scope)
33        contract_parser = ContractVyper(self, contract, data)
34        contract.set_offset(data.src, self._compilation_unit)
35
36        self._underlying_contract_to_parser[contract] = contract_parser
37
38    def parse_contracts(self):
39        for contract, contract_parser in self._underlying_contract_to_parser.items():
40            self._contracts_by_id[contract.id] = contract
41            self._compilation_unit.contracts.append(contract)
42
43            contract_parser.parse_enums()
44            contract_parser.parse_structs()
45            contract_parser.parse_state_variables()
46            contract_parser.parse_events()
47            contract_parser.parse_functions()
48
49        self._parsed = True
50
51    def analyze_contracts(self) -> None:
52        if not self._parsed:
53            raise SlitherException("Parse the contract before running analyses")
54
55        for contract_parser in self._underlying_contract_to_parser.values():
56            # State variables are analyzed for all contracts because interfaces may
57            # reference them, specifically, constants.
58            contract_parser.analyze_state_variables()
59
60        for contract_parser in self._underlying_contract_to_parser.values():
61            contract_parser.analyze()
62
63        self._convert_to_slithir()
64
65        compute_dependency(self._compilation_unit)
66
67        self._analyzed = True
68
69    def _convert_to_slithir(self) -> None:
70        for contract in self._compilation_unit.contracts:
71            contract.add_constructor_variables()
72            for func in contract.functions:
73                func.generate_slithir_and_analyze()
74
75            contract.convert_expression_to_slithir_ssa()
76
77        self._compilation_unit.propagate_function_calls()
78        for contract in self._compilation_unit.contracts:
79            contract.fix_phi()
80            contract.update_read_write_using_ssa()
class VyperCompilationUnit:
15class VyperCompilationUnit:
16    _compilation_unit: SlitherCompilationUnit
17    _parsed: bool = False
18    _analyzed: bool = False
19    _underlying_contract_to_parser: Dict[Contract, ContractVyper] = field(default_factory=dict)
20    _contracts_by_id: Dict[int, Contract] = field(default_factory=dict)
21
22    def parse_module(self, data: Module, filename: str):
23
24        sourceUnit_candidates = re.findall("[0-9]*:[0-9]*:([0-9]*)", data.src)
25        assert len(sourceUnit_candidates) == 1, "Source unit not found"
26        sourceUnit = int(sourceUnit_candidates[0])
27
28        self._compilation_unit.source_units[sourceUnit] = filename
29        if os.path.isfile(filename) and filename not in self._compilation_unit.core.source_code:
30            self._compilation_unit.core.add_source_code(filename)
31
32        scope = self._compilation_unit.get_scope(filename)
33        contract = Contract(self._compilation_unit, scope)
34        contract_parser = ContractVyper(self, contract, data)
35        contract.set_offset(data.src, self._compilation_unit)
36
37        self._underlying_contract_to_parser[contract] = contract_parser
38
39    def parse_contracts(self):
40        for contract, contract_parser in self._underlying_contract_to_parser.items():
41            self._contracts_by_id[contract.id] = contract
42            self._compilation_unit.contracts.append(contract)
43
44            contract_parser.parse_enums()
45            contract_parser.parse_structs()
46            contract_parser.parse_state_variables()
47            contract_parser.parse_events()
48            contract_parser.parse_functions()
49
50        self._parsed = True
51
52    def analyze_contracts(self) -> None:
53        if not self._parsed:
54            raise SlitherException("Parse the contract before running analyses")
55
56        for contract_parser in self._underlying_contract_to_parser.values():
57            # State variables are analyzed for all contracts because interfaces may
58            # reference them, specifically, constants.
59            contract_parser.analyze_state_variables()
60
61        for contract_parser in self._underlying_contract_to_parser.values():
62            contract_parser.analyze()
63
64        self._convert_to_slithir()
65
66        compute_dependency(self._compilation_unit)
67
68        self._analyzed = True
69
70    def _convert_to_slithir(self) -> None:
71        for contract in self._compilation_unit.contracts:
72            contract.add_constructor_variables()
73            for func in contract.functions:
74                func.generate_slithir_and_analyze()
75
76            contract.convert_expression_to_slithir_ssa()
77
78        self._compilation_unit.propagate_function_calls()
79        for contract in self._compilation_unit.contracts:
80            contract.fix_phi()
81            contract.update_read_write_using_ssa()
VyperCompilationUnit( _compilation_unit: slither.core.compilation_unit.SlitherCompilationUnit, _parsed: bool = False, _analyzed: bool = False, _underlying_contract_to_parser: Dict[slither.core.declarations.contract.Contract, slither.vyper_parsing.declarations.contract.ContractVyper] = <factory>, _contracts_by_id: Dict[int, slither.core.declarations.contract.Contract] = <factory>)
def parse_module(self, data: slither.vyper_parsing.ast.types.Module, filename: str):
22    def parse_module(self, data: Module, filename: str):
23
24        sourceUnit_candidates = re.findall("[0-9]*:[0-9]*:([0-9]*)", data.src)
25        assert len(sourceUnit_candidates) == 1, "Source unit not found"
26        sourceUnit = int(sourceUnit_candidates[0])
27
28        self._compilation_unit.source_units[sourceUnit] = filename
29        if os.path.isfile(filename) and filename not in self._compilation_unit.core.source_code:
30            self._compilation_unit.core.add_source_code(filename)
31
32        scope = self._compilation_unit.get_scope(filename)
33        contract = Contract(self._compilation_unit, scope)
34        contract_parser = ContractVyper(self, contract, data)
35        contract.set_offset(data.src, self._compilation_unit)
36
37        self._underlying_contract_to_parser[contract] = contract_parser
def parse_contracts(self):
39    def parse_contracts(self):
40        for contract, contract_parser in self._underlying_contract_to_parser.items():
41            self._contracts_by_id[contract.id] = contract
42            self._compilation_unit.contracts.append(contract)
43
44            contract_parser.parse_enums()
45            contract_parser.parse_structs()
46            contract_parser.parse_state_variables()
47            contract_parser.parse_events()
48            contract_parser.parse_functions()
49
50        self._parsed = True
def analyze_contracts(self) -> None:
52    def analyze_contracts(self) -> None:
53        if not self._parsed:
54            raise SlitherException("Parse the contract before running analyses")
55
56        for contract_parser in self._underlying_contract_to_parser.values():
57            # State variables are analyzed for all contracts because interfaces may
58            # reference them, specifically, constants.
59            contract_parser.analyze_state_variables()
60
61        for contract_parser in self._underlying_contract_to_parser.values():
62            contract_parser.analyze()
63
64        self._convert_to_slithir()
65
66        compute_dependency(self._compilation_unit)
67
68        self._analyzed = True