witx_codegen/assemblyscript/
common.rs

1use convert_case::{Case, Casing};
2
3use super::tuple::Tuple;
4use crate::astype::*;
5
6pub trait IsNullable {
7    fn is_nullable(&self) -> bool;
8}
9
10impl IsNullable for ASType {
11    fn is_nullable(&self) -> bool {
12        matches!(
13            self,
14            ASType::ConstPtr(_)
15                | ASType::MutPtr(_)
16                | ASType::ReadBuffer(_)
17                | ASType::WriteBuffer(_)
18                | ASType::Enum(_)
19                | ASType::Struct(_)
20                | ASType::Tuple(_)
21                | ASType::Union(_)
22        )
23    }
24}
25
26pub trait Normalize {
27    fn as_str(&self) -> &str;
28
29    fn as_type(&self) -> String {
30        self.as_str().to_case(Case::Pascal)
31    }
32
33    fn as_fn(&self) -> String {
34        self.as_str().to_case(Case::Camel)
35    }
36
37    fn as_fn_suffix(&self) -> String {
38        self.as_str().to_case(Case::UpperCamel)
39    }
40
41    fn as_var(&self) -> String {
42        escape_reserved_word(&self.as_str().to_case(Case::Snake))
43    }
44
45    fn as_const(&self) -> String {
46        self.as_str().to_case(Case::UpperSnake)
47    }
48
49    fn as_namespace(&self) -> String {
50        self.as_str().to_case(Case::Pascal)
51    }
52}
53
54impl<T: AsRef<str>> Normalize for T {
55    fn as_str(&self) -> &str {
56        self.as_ref()
57    }
58}
59
60pub trait ToLanguageRepresentation {
61    fn as_astype(&self) -> &ASType;
62
63    fn to_string(&self) -> String {
64        self.as_lang()
65    }
66
67    fn as_lang(&self) -> String {
68        match self.as_astype() {
69            ASType::Alias(alias) => alias.name.as_type(),
70            ASType::Bool => "bool".to_string(),
71            ASType::Char32 => "Char32".to_string(),
72            ASType::Char8 => "Char8".to_string(),
73            ASType::F32 => "f32".to_string(),
74            ASType::F64 => "f64".to_string(),
75            ASType::Handle(_resource_name) => "WasiHandle".to_string(),
76            ASType::ConstPtr(pointee) => format!("WasiPtr<{}>", pointee.to_string()),
77            ASType::MutPtr(pointee) => format!("WasiMutPtr<{}>", pointee.to_string()),
78            ASType::Option(_) => todo!(),
79            ASType::Result(_) => todo!(),
80            ASType::S8 => "i8".to_string(),
81            ASType::S16 => "i16".to_string(),
82            ASType::S32 => "i32".to_string(),
83            ASType::S64 => "i64".to_string(),
84            ASType::U8 => "u8".to_string(),
85            ASType::U16 => "u16".to_string(),
86            ASType::U32 => "u32".to_string(),
87            ASType::U64 => "u64".to_string(),
88            ASType::USize => "usize".to_string(),
89            ASType::Void => "void".to_string(),
90            ASType::Constants(_) => unimplemented!(),
91            ASType::Enum(enum_) => {
92                format!("{} /* Enum */", enum_.repr.as_ref().as_lang())
93            }
94            ASType::Struct(_) => unimplemented!(),
95            ASType::Tuple(tuple_members) => Tuple::name_for(tuple_members).as_type(),
96            ASType::Union(_) => unimplemented!(),
97            ASType::Slice(element_type) => format!("WasiMutSlice<{}>", element_type.as_lang()),
98            ASType::String(_) => "WasiString".to_string(),
99            ASType::ReadBuffer(element_type) => format!("WasiSlice<{}>", element_type.as_lang()),
100            ASType::WriteBuffer(element_type) => {
101                format!("WasiMutSlice<{}>", element_type.to_string())
102            }
103        }
104    }
105}
106
107impl ToLanguageRepresentation for ASType {
108    fn as_astype(&self) -> &ASType {
109        self
110    }
111}
112
113pub fn escape_reserved_word(word: &str) -> String {
114    if RESERVED.iter().any(|k| *k == word) {
115        // If the camel-cased string matched any strict or reserved keywords, then
116        // append a trailing underscore to the identifier we generate.
117        format!("{}_", word)
118    } else {
119        word.to_string() // Otherwise, use the string as is.
120    }
121}
122
123/// Reserved Keywords.
124///
125/// Source: [ECMAScript 2022 Language Specification](https://tc39.es/ecma262/#sec-keywords-and-reserved-words)
126const RESERVED: &[&str] = &[
127    "await",
128    "break",
129    "case",
130    "catch",
131    "class",
132    "const",
133    "continue",
134    "debugger",
135    "default",
136    "delete",
137    "do",
138    "else",
139    "enum",
140    "export",
141    "extends",
142    "false",
143    "finally",
144    "for",
145    "function",
146    "if",
147    "import",
148    "in",
149    "instanceof",
150    "new",
151    "null",
152    "return",
153    "super",
154    "switch",
155    "this",
156    "throw",
157    "true",
158    "try",
159    "typeof",
160    "var",
161    "void",
162    "while",
163    "with",
164    "yield",
165    "let",
166    "static",
167    "implements",
168    "interface",
169    "package",
170    "private",
171    "protected",
172    "and",
173    "public",
174];