/
lib.rs
132 lines (115 loc) · 3.39 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
mod r#async;
mod callbacks;
mod cfg;
mod classes;
mod constants;
mod delegates;
mod enums;
mod extensions;
mod functions;
mod gen;
mod handles;
mod helpers;
mod implements;
mod interfaces;
mod iterator;
mod method_names;
mod methods;
mod names;
mod replacements;
mod signatures;
mod structs;
use cfg::*;
use functions::*;
pub use gen::*;
use helpers::*;
use iterator::*;
use metadata::*;
use method_names::*;
use methods::*;
use names::*;
use r#async::*;
use signatures::*;
use tokens::*;
pub fn gen_type(name: &str, gen: &Gen) -> String {
let reader = TypeReader::get();
let mut tokens = String::new();
for def in reader.get_type_entry(TypeName::parse(name)).iter().flat_map(|entry| entry.iter()) {
tokens.push_str(gen_element_type(def, gen).as_str());
}
assert!(!tokens.is_empty(), "`{}` not found", name);
tokens
}
pub fn gen_namespace(gen: &Gen) -> String {
let tree = TypeReader::get().get_namespace(gen.namespace).expect("Namespace not found");
let namespaces = tree.namespaces.iter().map(move |(name, tree)| {
if tree.namespace == "Windows.Win32.Interop" {
return quote! {};
}
let name = gen_ident(name);
let namespace = tree.namespace[tree.namespace.find('.').unwrap() + 1..].replace('.', "_");
quote! {
#[cfg(feature = #namespace)] pub mod #name;
}
});
let functions = gen_sys_functions(tree, gen);
let types = gen_non_sys_function_types(tree, gen);
let tokens = quote! {
#![allow(non_snake_case, non_camel_case_types, non_upper_case_globals, clashing_extern_declarations, clippy::all)]
#(#namespaces)*
#functions
#types
};
tokens.into_string()
}
pub fn gen_namespace_impl(gen: &Gen) -> String {
let tree = TypeReader::get().get_namespace(gen.namespace).expect("Namespace not found");
let mut tokens = TokenStream::new();
for entry in tree.types.values() {
for def in entry {
if let ElementType::TypeDef(def) = def {
let def = &def.clone().with_generics();
tokens.combine(&implements::gen(def, gen));
}
}
}
tokens.into_string()
}
fn gen_non_sys_function_types(tree: &TypeTree, gen: &Gen) -> TokenStream {
let mut tokens = TokenStream::new();
for entry in tree.types.values() {
for def in entry {
tokens.combine(&gen_element_type(def, gen));
}
}
tokens
}
fn gen_element_type(def: &ElementType, gen: &Gen) -> TokenStream {
match def {
ElementType::Field(def) => constants::gen(def, gen),
ElementType::TypeDef(def) => {
let def = &def.clone().with_generics();
match def.kind() {
TypeKind::Class => classes::gen(def, gen),
TypeKind::Interface => interfaces::gen(def, gen),
TypeKind::Enum => enums::gen(def, gen),
TypeKind::Struct => structs::gen(def, gen),
TypeKind::Delegate => {
if def.is_winrt() {
delegates::gen(def, gen)
} else {
callbacks::gen(def, gen)
}
}
}
}
ElementType::MethodDef(def) => {
if !gen.sys {
gen_function(def, gen)
} else {
quote! {}
}
}
_ => quote! {},
}
}