Skip to content

Commit 827f120

Browse files
committed
gnd: Consolidate reserved words and sanitization utilities
Extract RESERVED_WORDS, handle_reserved_word(), and capitalize() into a shared module to reduce code duplication across codegen. Previously these utilities were duplicated in: - codegen/schema.rs (RESERVED_WORDS with 47 items, handle_reserved_word) - codegen/abi.rs (RESERVED_WORDS with 43 items, handle_reserved_word, capitalize) The shared module uses a unified RESERVED_WORDS list that includes all words from both lists (including "await" from abi.rs).
1 parent 630f7eb commit 827f120

File tree

5 files changed

+122
-121
lines changed

5 files changed

+122
-121
lines changed

gnd/src/codegen/abi.rs

Lines changed: 1 addition & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use regex::Regex;
1212
use serde_json::Value as JsonValue;
1313

1414
use super::typescript::{self as ts, Class, ClassMember, Method, ModuleImports, Param as TsParam};
15+
use crate::shared::{capitalize, handle_reserved_word};
1516

1617
/// Represents component name information extracted from ABI JSON.
1718
/// This is needed because ethabi's `ParamType::Tuple` loses the component names.
@@ -127,69 +128,6 @@ fn parse_abi_component_names(abi_json: &str) -> HashMap<ComponentLookupKey, Comp
127128
result
128129
}
129130

130-
/// Reserved words in AssemblyScript that need to be escaped.
131-
const RESERVED_WORDS: &[&str] = &[
132-
"await",
133-
"break",
134-
"case",
135-
"catch",
136-
"class",
137-
"const",
138-
"continue",
139-
"debugger",
140-
"delete",
141-
"do",
142-
"else",
143-
"enum",
144-
"export",
145-
"extends",
146-
"false",
147-
"finally",
148-
"function",
149-
"if",
150-
"implements",
151-
"import",
152-
"in",
153-
"interface",
154-
"let",
155-
"new",
156-
"package",
157-
"private",
158-
"protected",
159-
"public",
160-
"return",
161-
"super",
162-
"switch",
163-
"static",
164-
"this",
165-
"throw",
166-
"true",
167-
"try",
168-
"typeof",
169-
"var",
170-
"while",
171-
"with",
172-
"yield",
173-
];
174-
175-
/// Handle reserved words by appending an underscore.
176-
fn handle_reserved_word(name: &str) -> String {
177-
if RESERVED_WORDS.contains(&name) {
178-
format!("{}_", name)
179-
} else {
180-
name.to_string()
181-
}
182-
}
183-
184-
/// Capitalize the first letter of a string.
185-
fn capitalize(s: &str) -> String {
186-
let mut chars = s.chars();
187-
match chars.next() {
188-
None => String::new(),
189-
Some(c) => c.to_uppercase().collect::<String>() + chars.as_str(),
190-
}
191-
}
192-
193131
const GRAPH_TS_MODULE: &str = "@graphprotocol/graph-ts";
194132

195133
/// ABI code generator.

gnd/src/codegen/schema.rs

Lines changed: 1 addition & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -10,64 +10,7 @@ use super::typescript::{
1010
self as ts, ArrayType, Class, Method, ModuleImports, NamedType, NullableType, Param,
1111
StaticMethod, TypeExpr,
1212
};
13-
14-
/// Reserved words in AssemblyScript that need to be escaped.
15-
const RESERVED_WORDS: &[&str] = &[
16-
"break",
17-
"case",
18-
"catch",
19-
"class",
20-
"const",
21-
"continue",
22-
"debugger",
23-
"default",
24-
"delete",
25-
"do",
26-
"else",
27-
"enum",
28-
"export",
29-
"extends",
30-
"false",
31-
"finally",
32-
"for",
33-
"function",
34-
"if",
35-
"implements",
36-
"import",
37-
"in",
38-
"instanceof",
39-
"interface",
40-
"let",
41-
"new",
42-
"null",
43-
"package",
44-
"private",
45-
"protected",
46-
"public",
47-
"return",
48-
"static",
49-
"super",
50-
"switch",
51-
"this",
52-
"throw",
53-
"true",
54-
"try",
55-
"typeof",
56-
"var",
57-
"void",
58-
"while",
59-
"with",
60-
"yield",
61-
];
62-
63-
/// Handle reserved words by appending an underscore.
64-
fn handle_reserved_word(name: &str) -> String {
65-
if RESERVED_WORDS.contains(&name) {
66-
format!("{}_", name)
67-
} else {
68-
name.to_string()
69-
}
70-
}
13+
use crate::shared::handle_reserved_word;
7114

7215
/// Type of the ID field.
7316
#[derive(Debug, Clone, Copy, PartialEq, Eq)]

gnd/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub mod output;
99
pub mod prompt;
1010
pub mod scaffold;
1111
pub mod services;
12+
pub mod shared;
1213
pub mod validation;
1314
pub mod watch;
1415
pub mod watcher;

gnd/src/shared/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//! Shared utilities for gnd code generation.
2+
//!
3+
//! This module contains common utilities used across multiple codegen
4+
//! and scaffold modules to reduce duplication.
5+
6+
pub mod sanitize;
7+
8+
pub use sanitize::{capitalize, handle_reserved_word, RESERVED_WORDS};

gnd/src/shared/sanitize.rs

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
//! Shared sanitization utilities for code generation.
2+
//!
3+
//! Contains reserved word handling and name sanitization used by both
4+
//! schema codegen and ABI codegen.
5+
6+
/// Reserved words in AssemblyScript that need to be escaped.
7+
///
8+
/// This is a superset of reserved words from ECMAScript plus AssemblyScript-specific
9+
/// additions. When a field or parameter name matches one of these, it gets
10+
/// an underscore appended.
11+
pub const RESERVED_WORDS: &[&str] = &[
12+
"await",
13+
"break",
14+
"case",
15+
"catch",
16+
"class",
17+
"const",
18+
"continue",
19+
"debugger",
20+
"default",
21+
"delete",
22+
"do",
23+
"else",
24+
"enum",
25+
"export",
26+
"extends",
27+
"false",
28+
"finally",
29+
"for",
30+
"function",
31+
"if",
32+
"implements",
33+
"import",
34+
"in",
35+
"instanceof",
36+
"interface",
37+
"let",
38+
"new",
39+
"null",
40+
"package",
41+
"private",
42+
"protected",
43+
"public",
44+
"return",
45+
"static",
46+
"super",
47+
"switch",
48+
"this",
49+
"throw",
50+
"true",
51+
"try",
52+
"typeof",
53+
"var",
54+
"void",
55+
"while",
56+
"with",
57+
"yield",
58+
];
59+
60+
/// Handle reserved words by appending an underscore.
61+
///
62+
/// If the given name is a reserved word in AssemblyScript, returns the name
63+
/// with an underscore appended. Otherwise returns the name unchanged.
64+
pub fn handle_reserved_word(name: &str) -> String {
65+
if RESERVED_WORDS.contains(&name) {
66+
format!("{}_", name)
67+
} else {
68+
name.to_string()
69+
}
70+
}
71+
72+
/// Capitalize the first letter of a string.
73+
///
74+
/// Returns an empty string if the input is empty, otherwise returns the
75+
/// string with the first character uppercased.
76+
pub fn capitalize(s: &str) -> String {
77+
let mut chars = s.chars();
78+
match chars.next() {
79+
None => String::new(),
80+
Some(c) => c.to_uppercase().collect::<String>() + chars.as_str(),
81+
}
82+
}
83+
84+
#[cfg(test)]
85+
mod tests {
86+
use super::*;
87+
88+
#[test]
89+
fn test_handle_reserved_word_reserved() {
90+
assert_eq!(handle_reserved_word("class"), "class_");
91+
assert_eq!(handle_reserved_word("return"), "return_");
92+
assert_eq!(handle_reserved_word("await"), "await_");
93+
assert_eq!(handle_reserved_word("default"), "default_");
94+
}
95+
96+
#[test]
97+
fn test_handle_reserved_word_not_reserved() {
98+
assert_eq!(handle_reserved_word("myField"), "myField");
99+
assert_eq!(handle_reserved_word("amount"), "amount");
100+
assert_eq!(handle_reserved_word("value"), "value");
101+
}
102+
103+
#[test]
104+
fn test_capitalize() {
105+
assert_eq!(capitalize("hello"), "Hello");
106+
assert_eq!(capitalize("world"), "World");
107+
assert_eq!(capitalize(""), "");
108+
assert_eq!(capitalize("a"), "A");
109+
assert_eq!(capitalize("ALREADY"), "ALREADY");
110+
}
111+
}

0 commit comments

Comments
 (0)