neo_solidity/solidity/
solidity_metadata.rs

1#[derive(Debug, Clone, Default)]
2pub struct SelectorRegistry {
3    /// Mapping of Solidity type name -> method name -> list of selectors (one per overload).
4    ///
5    /// This supports lowering expressions like `IERC20.transfer.selector` into a constant
6    /// `bytes4` value and allows recovering Neo method names from `.selector` expressions in
7    /// low-level EVM call shims (`abi.encodeWithSelector(...)`).
8    pub type_method_selectors:
9        std::collections::HashMap<String, std::collections::HashMap<String, Vec<[u8; 4]>>>,
10    /// Set of known Solidity interface type names visible to the compilation unit.
11    pub interface_types: std::collections::HashSet<String>,
12}
13
14#[derive(Debug, Clone)]
15pub struct ContractMetadata {
16    pub name: String,
17    /// Whether this contract was declared `abstract`.
18    pub is_abstract: bool,
19    /// Whether this contract was declared as a `library`.
20    pub is_library: bool,
21    pub methods: Vec<FunctionMetadata>,
22    pub events: Vec<EventMetadata>,
23    pub uses_storage: bool,
24    pub state_variables: Vec<StateVariableMetadata>,
25    pub structs: Vec<StructMetadata>,
26    pub enums: Vec<EnumMetadata>,
27    /// All contract/interface type names visible to this compilation unit.
28    ///
29    /// This is used during IR lowering to recognize Solidity-style contract casts
30    /// like `IERC20(token).transfer(...)` without accidentally treating unknown
31    /// function calls as casts.
32    pub contract_types: Vec<String>,
33    /// Registry of known function selectors for contract/interface types visible to this
34    /// compilation unit (shared across contracts via `Arc`).
35    pub selector_registry: std::sync::Arc<SelectorRegistry>,
36    /// Natspec documentation for the contract
37    pub documentation: NatspecDoc,
38    /// Whether this contract contains `using X for *` directives.
39    pub has_using_for_star: bool,
40    /// Whether this contract contains `using { f, g } for Y` directives.
41    pub has_using_function_list: bool,
42    /// Library names referenced by `using X for Y` directives.
43    pub using_for_libraries: Vec<String>,
44    /// Whether this contract contains `type X is Y` definitions.
45    pub has_type_definitions: bool,
46    /// User-defined value type aliases (`type X is Y`).
47    /// Maps type name to underlying Solidity type string.
48    pub type_aliases: std::collections::HashMap<String, String>,
49    /// Warnings collected during inheritance flattening (e.g. virtual/override checks).
50    pub flatten_warnings: Vec<String>,
51    /// Mapping from original method name to the renamed super-method name.
52    /// Populated during inheritance flattening so `super.method()` can resolve.
53    pub super_method_map: std::collections::HashMap<String, String>,
54}
55
56#[derive(Debug, Clone)]
57pub struct FunctionMetadata {
58    pub name: String,
59    /// Neo entrypoint name. This may be mangled to disambiguate overloaded
60    /// Solidity functions because Neo ABI dispatches by name+arg count.
61    pub neo_name: String,
62    pub kind: FunctionKind,
63    pub parameters: Vec<ParameterMetadata>,
64    pub return_parameters: Vec<ParameterMetadata>,
65    pub state_mutability: StateMutability,
66    pub visibility: VisibilityKind,
67    pub offset: u32,
68    pub body: Option<Statement>,
69    pub selector: [u8; 4],
70    /// Whether this function is marked `virtual`.
71    pub is_virtual: bool,
72    /// Whether this function is marked `override`.
73    pub is_override: bool,
74    /// Natspec documentation for the function
75    pub documentation: NatspecDoc,
76}
77
78#[derive(Debug, Clone, Copy, PartialEq, Eq)]
79pub enum FunctionKind {
80    Constructor,
81    Regular,
82}
83
84#[derive(Debug, Clone)]
85pub struct ParameterMetadata {
86    pub name: Option<String>,
87    pub ty: String,
88    pub neo_type: Option<NeoType>,
89    pub storage: Option<String>,
90}
91
92#[derive(Debug, Clone)]
93pub struct EventMetadata {
94    pub name: String,
95    pub normalized_name: String,
96    pub parameters: Vec<EventParameter>,
97}
98
99#[derive(Debug, Clone)]
100pub struct EventParameter {
101    pub name: Option<String>,
102    pub ty: String,
103    pub indexed: bool,
104}
105
106#[derive(Debug, Clone)]
107pub struct StateVariableMetadata {
108    pub name: Option<String>,
109    pub ty: String,
110    pub is_constant: bool,
111    pub is_immutable: bool,
112    pub visibility: Option<String>,
113    pub neo_type: Option<NeoType>,
114    pub has_initializer: bool,
115    pub initializer: Option<Expression>,
116}
117
118#[derive(Debug, Clone)]
119pub struct StructMetadata {
120    pub name: String,
121    pub fields: Vec<StructFieldMetadata>,
122}
123
124#[derive(Debug, Clone)]
125pub struct StructFieldMetadata {
126    pub name: String,
127    pub ty: String,
128}
129
130#[derive(Debug, Clone)]
131pub struct EnumMetadata {
132    pub name: String,
133    pub values: Vec<String>,
134}
135
136#[derive(Debug, Clone, Copy, PartialEq, Eq)]
137pub enum StateMutability {
138    Pure,
139    View,
140    NonPayable,
141    Payable,
142}
143
144impl StateMutability {
145    pub fn is_safe(self) -> bool {
146        matches!(self, StateMutability::Pure | StateMutability::View)
147    }
148}
149
150#[derive(Debug, Clone, Copy, PartialEq, Eq)]
151pub enum DiagnosticSeverity {
152    Warning,
153    Error,
154}
155
156#[derive(Debug, Clone)]
157pub struct Diagnostic {
158    pub severity: DiagnosticSeverity,
159    pub message: String,
160    pub code: Option<String>,
161    pub suggestion: Option<String>,
162}
163
164impl Diagnostic {
165    /// Create a warning diagnostic.
166    pub fn warning(message: impl Into<String>) -> Self {
167        Self {
168            severity: DiagnosticSeverity::Warning,
169            message: message.into(),
170            code: None,
171            suggestion: None,
172        }
173    }
174
175    /// Create an error diagnostic.
176    pub fn error(message: impl Into<String>) -> Self {
177        Self {
178            severity: DiagnosticSeverity::Error,
179            message: message.into(),
180            code: None,
181            suggestion: None,
182        }
183    }
184
185    /// Attach a diagnostic code (e.g. "W101", "E042").
186    pub fn with_code(mut self, code: impl Into<String>) -> Self {
187        self.code = Some(code.into());
188        self
189    }
190
191    /// Attach an actionable fix suggestion.
192    pub fn with_suggestion(mut self, suggestion: impl Into<String>) -> Self {
193        self.suggestion = Some(suggestion.into());
194        self
195    }
196}