Skip to content

Commit f491e0d

Browse files
authored
feat!: make most structs non exhaustive and add builders (#25)
1 parent 7b6ec13 commit f491e0d

15 files changed

+308
-14
lines changed

Cargo.lock

+36
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ version = "0.1.6"
1313

1414
[dependencies]
1515
anyhow = "1.0.95"
16+
bon = "3.3.2"
1617
clap = { version = "4.5.29", features = ["derive"] }
1718
derive_more = { version = "2.0.1", features = ["from", "display"] }
1819
dotenvy = "0.15.7"

src/config.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ pub struct Args {
6363
pub compact: Option<bool>,
6464
}
6565

66-
#[derive(Debug, Clone, Serialize, Deserialize)]
66+
#[derive(Debug, Clone, Serialize, Deserialize, bon::Builder)]
67+
#[non_exhaustive]
68+
#[builder(on(PathBuf, into))]
6769
pub struct Config {
6870
pub paths: Vec<PathBuf>,
6971
pub exclude: Vec<PathBuf>,

src/definitions/constructor.rs

+50-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ use super::{
1212
};
1313

1414
/// A constructor definition
15-
#[derive(Debug, Clone)]
15+
#[derive(Debug, Clone, bon::Builder)]
16+
#[non_exhaustive]
1617
pub struct ConstructorDefinition {
1718
pub parent: Option<Parent>,
1819
pub span: TextRange,
@@ -94,3 +95,51 @@ impl Validate for ConstructorDefinition {
9495
out
9596
}
9697
}
98+
99+
#[cfg(test)]
100+
mod tests {
101+
use semver::Version;
102+
use slang_solidity::parser::Parser;
103+
104+
use super::*;
105+
106+
static OPTIONS: ValidationOptions = ValidationOptions {
107+
inheritdoc: false,
108+
constructor: true,
109+
enum_params: false,
110+
};
111+
112+
fn parse_file(contents: &str) -> ConstructorDefinition {
113+
let parser = Parser::create(Version::new(0, 8, 0)).unwrap();
114+
let output = parser.parse(NonterminalKind::SourceUnit, contents);
115+
assert!(output.is_valid(), "{:?}", output.errors());
116+
let cursor = output.create_tree_cursor();
117+
let m = cursor
118+
.query(vec![ConstructorDefinition::query()])
119+
.next()
120+
.unwrap();
121+
let def = ConstructorDefinition::extract(m).unwrap();
122+
def.as_constructor().unwrap()
123+
}
124+
125+
#[test]
126+
fn test_constructor() {
127+
let contents = "contract Test {
128+
/// @param param1 Test
129+
/// @param param2 Test2
130+
constructor(uint256 param1, bytes calldata param2) { }
131+
}";
132+
let res = parse_file(contents).validate(&OPTIONS);
133+
assert!(res.diags.is_empty(), "{:#?}", res.diags);
134+
}
135+
136+
#[test]
137+
fn test_constructor_no_natspec() {
138+
let contents = "contract Test {
139+
constructor(uint256 param1, bytes calldata param2) { }
140+
}";
141+
let res = parse_file(contents).validate(&OPTIONS);
142+
assert_eq!(res.diags.len(), 1);
143+
assert_eq!(res.diags[0].message, "missing NatSpec");
144+
}
145+
}

src/definitions/enumeration.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ use super::{
1212
};
1313

1414
/// An enum definition
15-
#[derive(Debug, Clone)]
15+
#[derive(Debug, Clone, bon::Builder)]
16+
#[non_exhaustive]
17+
#[builder(on(String, into))]
1618
pub struct EnumDefinition {
1719
pub parent: Option<Parent>,
1820
pub name: String,

src/definitions/error.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ use super::{
1212
};
1313

1414
/// An error definition
15-
#[derive(Debug, Clone)]
15+
#[derive(Debug, Clone, bon::Builder)]
16+
#[non_exhaustive]
17+
#[builder(on(String, into))]
1618
pub struct ErrorDefinition {
1719
pub parent: Option<Parent>,
1820
pub name: String,

src/definitions/event.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ use super::{
1212
};
1313

1414
/// An event definition
15-
#[derive(Debug, Clone)]
15+
#[derive(Debug, Clone, bon::Builder)]
16+
#[non_exhaustive]
17+
#[builder(on(String, into))]
1618
pub struct EventDefinition {
1719
pub parent: Option<Parent>,
1820
pub name: String,

src/definitions/function.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ use super::{
1313
};
1414

1515
/// A function definition
16-
#[derive(Debug, Clone)]
16+
#[derive(Debug, Clone, bon::Builder)]
17+
#[non_exhaustive]
18+
#[builder(on(String, into))]
1719
pub struct FunctionDefinition {
1820
pub parent: Option<Parent>,
1921
pub name: String,

src/definitions/mod.rs

+70-3
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ pub fn capture_opt(m: &QueryMatch, name: &str) -> Result<Option<Cursor>> {
4545
}
4646

4747
/// Validation options to control which lints generate a diagnostic
48-
#[derive(Debug, Clone)]
48+
#[derive(Debug, Clone, bon::Builder)]
49+
#[non_exhaustive]
4950
pub struct ValidationOptions {
5051
/// Whether overridden, public and external functions should have an `@inheritdoc`
5152
pub inheritdoc: bool,
@@ -105,7 +106,8 @@ pub trait Validate {
105106
/// An identifier (named or unnamed) and its span
106107
///
107108
/// Unnamed identifiers are used for unnamed return params.
108-
#[derive(Debug, Clone)]
109+
#[derive(Debug, Clone, bon::Builder)]
110+
#[builder(on(String, into))]
109111
pub struct Identifier {
110112
pub name: Option<String>,
111113
pub span: TextRange,
@@ -124,7 +126,8 @@ pub enum Visibility {
124126
}
125127

126128
/// Attributes for a function or state variable (visibility and override)
127-
#[derive(Debug, Clone, Copy, Default)]
129+
#[derive(Debug, Clone, Copy, Default, bon::Builder)]
130+
#[non_exhaustive]
128131
pub struct Attributes {
129132
pub visibility: Visibility,
130133
pub r#override: bool,
@@ -185,6 +188,70 @@ impl Definition {
185188
Definition::Variable(def) => def.validate(options),
186189
}
187190
}
191+
192+
/// Retrieve the inner constructor definition
193+
pub fn as_constructor(self) -> Option<ConstructorDefinition> {
194+
match self {
195+
Definition::Constructor(def) => Some(def),
196+
_ => None,
197+
}
198+
}
199+
200+
/// Retrieve the inner enum definition
201+
pub fn as_enum(self) -> Option<EnumDefinition> {
202+
match self {
203+
Definition::Enumeration(def) => Some(def),
204+
_ => None,
205+
}
206+
}
207+
208+
/// Retrieve the inner error definition
209+
pub fn as_error(self) -> Option<ErrorDefinition> {
210+
match self {
211+
Definition::Error(def) => Some(def),
212+
_ => None,
213+
}
214+
}
215+
216+
/// Retrieve the inner event definition
217+
pub fn as_event(self) -> Option<EventDefinition> {
218+
match self {
219+
Definition::Event(def) => Some(def),
220+
_ => None,
221+
}
222+
}
223+
224+
/// Retrieve the inner function definition
225+
pub fn as_function(self) -> Option<FunctionDefinition> {
226+
match self {
227+
Definition::Function(def) => Some(def),
228+
_ => None,
229+
}
230+
}
231+
232+
/// Retrieve the inner modifier definition
233+
pub fn as_modifier(self) -> Option<ModifierDefinition> {
234+
match self {
235+
Definition::Modifier(def) => Some(def),
236+
_ => None,
237+
}
238+
}
239+
240+
/// Retrieve the inner struct definition
241+
pub fn as_struct(self) -> Option<StructDefinition> {
242+
match self {
243+
Definition::Struct(def) => Some(def),
244+
_ => None,
245+
}
246+
}
247+
248+
/// Retrieve the inner variable declaration
249+
pub fn as_variable(self) -> Option<VariableDeclaration> {
250+
match self {
251+
Definition::Variable(def) => Some(def),
252+
_ => None,
253+
}
254+
}
188255
}
189256

190257
/// Find source item definitions from a root CST cursor

src/definitions/modifier.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ use super::{
1212
};
1313

1414
/// A modifier definition
15-
#[derive(Debug, Clone)]
15+
#[derive(Debug, Clone, bon::Builder)]
16+
#[non_exhaustive]
17+
#[builder(on(String, into))]
1618
pub struct ModifierDefinition {
1719
pub parent: Option<Parent>,
1820
pub name: String,

src/definitions/structure.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ use super::{
1212
};
1313

1414
/// A struct definition
15-
#[derive(Debug, Clone)]
15+
#[derive(Debug, Clone, bon::Builder)]
16+
#[non_exhaustive]
17+
#[builder(on(String, into))]
1618
pub struct StructDefinition {
1719
pub parent: Option<Parent>,
1820
pub name: String,

src/definitions/variable.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ use super::{
1212
};
1313

1414
/// A state variable declaration
15-
#[derive(Debug, Clone)]
15+
#[derive(Debug, Clone, bon::Builder)]
16+
#[non_exhaustive]
17+
#[builder(on(String, into))]
1618
pub struct VariableDeclaration {
1719
pub parent: Option<Parent>,
1820
pub name: String,

src/lint.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ pub struct FileDiagnostics {
3232
}
3333

3434
/// Diagnostics for a single source item (function, struct, etc.)
35-
#[derive(Debug, Clone, Serialize)]
35+
#[derive(Debug, Clone, Serialize, bon::Builder)]
36+
#[non_exhaustive]
37+
#[builder(on(String, into))]
3638
pub struct ItemDiagnostics {
3739
/// The parent contract, interface or library's name
3840
pub parent: Option<Parent>,

src/natspec.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ impl NatSpec {
6767
}
6868

6969
/// A single NatSpec item
70-
#[derive(Debug, Clone, PartialEq, Eq)]
70+
#[derive(Debug, Clone, PartialEq, Eq, bon::Builder)]
71+
#[non_exhaustive]
72+
#[builder(on(String, into))]
7173
pub struct NatSpecItem {
7274
/// The kind of NatSpec (notice, dev, param, etc.)
7375
pub kind: NatSpecKind,

0 commit comments

Comments
 (0)