Skip to content

Commit e306352

Browse files
committed
feat: (wip) compiler error and warnings
1 parent 35eb54d commit e306352

File tree

4 files changed

+204
-77
lines changed

4 files changed

+204
-77
lines changed

cli/src/analyser/mod.rs

Lines changed: 124 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
1+
use std::path::Path;
12
use tucana::shared::{DataTypeIdentifier, DefinitionDataType, FlowType, RuntimeFunctionDefinition};
23
use tucana::shared::data_type_identifier::Type;
34
use tucana::shared::definition_data_type_rule::Config;
5+
use code0_definition_reader::reader::{MetaType, ParsableDefinition, Reader};
6+
use crate::formatter::{error, warning};
47

58
#[derive(Clone)]
69
pub struct AnalysableDataType {
7-
pub definition_data_type: DefinitionDataType,
10+
pub original_definition: ParsableDefinition,
11+
pub definition_data_type: DefinitionDataType,
812
pub id: i16
913
}
1014

11-
1215
pub struct AnalysableFlowType {
16+
pub original_definition: ParsableDefinition,
1317
pub flow_type: FlowType,
1418
pub id: i16
1519
}
1620

17-
1821
pub struct AnalysableFunction {
22+
pub original_definition: ParsableDefinition,
1923
pub function: RuntimeFunctionDefinition,
2024
pub id: i16
2125
}
@@ -28,6 +32,85 @@ pub struct Analyser {
2832

2933
impl Analyser {
3034

35+
pub fn new(path: &str) -> Analyser {
36+
let reader = match Reader::from_path(path) {
37+
Some(res) => res,
38+
None => {
39+
panic!("No definitions behind this path");
40+
}
41+
};
42+
43+
let mut current_index = 0;
44+
let mut collected_data_types: Vec<AnalysableDataType> = vec![];
45+
let mut collected_flow_types: Vec<AnalysableFlowType> = vec![];
46+
let mut collected_functions: Vec<AnalysableFunction> = vec![];
47+
48+
for features in reader.meta {
49+
match features.r#type {
50+
MetaType::FlowType => {
51+
for p_flow_type in &features.data {
52+
current_index += 1;
53+
match serde_json::from_str::<FlowType>(p_flow_type.definition_string.as_str()) {
54+
Ok(flow_type) => collected_flow_types.push(AnalysableFlowType {
55+
original_definition: p_flow_type.clone(),
56+
flow_type,
57+
id: current_index,
58+
}),
59+
Err(err) => {
60+
if let Some(str_path) = &p_flow_type.path {
61+
let path = Path::new(str_path);
62+
error(err.to_string(), format!("{:?}:{}:{}", path.display(), p_flow_type.starting_line, 1));
63+
}
64+
},
65+
}
66+
}
67+
},
68+
MetaType::DataType => {
69+
for p_data_type in &features.data {
70+
current_index += 1;
71+
match serde_json::from_str::<DefinitionDataType>(p_data_type.definition_string.as_str()) {
72+
Ok(data_type) => collected_data_types.push(AnalysableDataType {
73+
original_definition: p_data_type.clone(),
74+
definition_data_type: data_type,
75+
id: current_index,
76+
}),
77+
Err(err) => {
78+
if let Some(str_path) = &p_data_type.path {
79+
let path = Path::new(str_path);
80+
error(err.to_string(), format!("{}:{}:{}", path.display(), p_data_type.starting_line, 1));
81+
}
82+
},
83+
}
84+
}
85+
}
86+
MetaType::RuntimeFunction => {
87+
for p_function in &features.data {
88+
current_index += 1;
89+
match serde_json::from_str::<RuntimeFunctionDefinition>(p_function.definition_string.as_str()) {
90+
Ok(function) => collected_functions.push(AnalysableFunction {
91+
original_definition: p_function.clone(),
92+
function,
93+
id: current_index,
94+
}),
95+
Err(err) => {
96+
if let Some(str_path) = &p_function.path {
97+
let path = Path::new(str_path);
98+
error(err.to_string(), format!("{:?}:{}:{}", path.display(), p_function.starting_line, 1));
99+
}
100+
},
101+
}
102+
}
103+
}
104+
}
105+
}
106+
107+
Self {
108+
data_types: collected_data_types,
109+
functions: collected_functions,
110+
flow_types: collected_flow_types,
111+
}
112+
}
113+
31114
pub fn data_type_identifier_exists(&self, identifier: String, id: i16) -> bool {
32115

33116
for data_types in &self.data_types {
@@ -43,29 +126,33 @@ impl Analyser {
43126
false
44127
}
45128

129+
/// Checks (recursively) if the defined DataTypes are correct
46130
pub fn handle_data_type(&self, analysable_data_type: AnalysableDataType, data_type_identifier: DataTypeIdentifier) -> Vec<String> {
47-
48131
let data_type = analysable_data_type.definition_data_type.clone();
49-
132+
let path = format!(
133+
"{:?}:{}:{}",
134+
Path::new(&analysable_data_type.clone().original_definition.path.unwrap_or_default()).display(),
135+
analysable_data_type.original_definition.starting_line,
136+
1
137+
);
50138
let id = analysable_data_type.id;
51139
let mut result = vec![];
140+
52141
if let Some(r#type) = data_type_identifier.r#type {
53142
match r#type {
54143
Type::DataTypeIdentifier(identifier) => {
55144
if !self.data_type_identifier_exists(identifier.clone(), id) {
56-
println!("A Unknown DataType inside a rule was detected: {}", identifier)
145+
error(format!("`{}` uses a undefined data_type: `{}`!", analysable_data_type.definition_data_type.identifier, identifier), path);
57146
}
58147
}
59148
Type::GenericType(generic) => {
60149
if !self.data_type_identifier_exists(generic.data_type_identifier.clone(), id) {
61-
println!("A Unknown DataType inside a rule was detected: {}", generic.data_type_identifier)
150+
error(format!("`{}` uses a undefined data_type: `{}`!", analysable_data_type.definition_data_type.identifier, generic.data_type_identifier), path);
62151
}
63152

64153
for mapper in generic.generic_mappers {
65154
if data_type.generic_keys.contains(&mapper.target) {
66155
result.push(mapper.target.clone())
67-
} else {
68-
println!("A GenericKey was used that did not exists in this DataType: {}", mapper.target)
69156
}
70157

71158
for source in mapper.source {
@@ -78,7 +165,7 @@ impl Analyser {
78165
}
79166
}
80167
} else {
81-
println!("Type is undefined!")
168+
error(format!("`{}` has a data_type that's null!", analysable_data_type.definition_data_type.identifier), path);
82169
}
83170

84171
result
@@ -87,22 +174,27 @@ impl Analyser {
87174
pub fn analyse_data_type(&self, analysable_data_type: AnalysableDataType) {
88175
let id = analysable_data_type.id;
89176
let data_type = analysable_data_type.definition_data_type.clone();
90-
println!("Checking: {}", data_type.identifier.clone());
177+
let path = format!(
178+
"{:?}:{}:{}",
179+
Path::new(&analysable_data_type.clone().original_definition.path.unwrap_or_default()).display(),
180+
analysable_data_type.original_definition.starting_line,
181+
1
182+
);
91183
// Check if Identifier is duplicate
92184
if self.data_type_identifier_exists(data_type.identifier.clone(), id) {
93-
println!("Duplicate definition of type {}", data_type.identifier)
185+
error(format!("The data_type `{}` is already defined!", data_type.identifier), path.clone());
94186
}
95187

96188
// The variant 0 never should occur
97189
if data_type.variant == 0 {
98-
println!("Type {} detected varriant 0", data_type.identifier)
190+
error(format!("The variant of `{}` is 0 and thus incorrect!", data_type.identifier), path.clone());
99191
}
100192

101193
// Generic Keys are present. Search if they are referenced!
102194
if !data_type.generic_keys.is_empty() {
103195
let mut detected_generic_keys: Vec<String> = vec![];
104196
if data_type.rules.is_empty() {
105-
println!("Generic Keys are defined but never used!")
197+
error(format!("`{}` defined generic_keys but never uses one!", data_type.identifier), path.clone());
106198
}
107199

108200
for optional_rule in &data_type.rules {
@@ -112,71 +204,76 @@ impl Analyser {
112204
if let Some(data_type_identifier) = rule.data_type_identifier {
113205
detected_generic_keys.append(&mut self.handle_data_type(analysable_data_type.clone(), data_type_identifier))
114206
} else {
115-
println!("DataTypeIdentifier is undefined!")
207+
error(format!("`{}` uses a definition_data_type_contains_key_rule that is null!", data_type.identifier), path.clone());
116208
}
117209
}
118210
Config::ContainsType(rule) => {
119211
if let Some(data_type_identifier) = rule.data_type_identifier {
120212
detected_generic_keys.append(&mut self.handle_data_type(analysable_data_type.clone(), data_type_identifier))
121213
} else {
122-
println!("DataTypeIdentifier is undefined!")
214+
error(format!("`{}` uses a definition_data_type_contains_type_rule that is null!", data_type.identifier), path.clone());
123215
}
124216
}
125217
Config::ItemOfCollection(rule) => {
126218
if rule.items.is_empty() {
127-
println!("ItemOfCollection is defined but does not have any items!")
219+
error(format!("`{}` uses a definition_data_type_item_of_collection_rule without any defined items!", data_type.identifier), path.clone());
128220
}
129221
}
130222
Config::NumberRange(_) => {}
131223
Config::Regex(_) => {}
132224
Config::InputTypes(rule) => {
133225
if rule.input_types.is_empty() {
134-
println!("InputTypes is defined but does not have any inputs!")
226+
error(format!("`{}` uses a definition_data_type_input_types_rule without any defined inputs!", data_type.identifier), path.clone());
135227
}
136228

137229
for input_type in &rule.input_types {
138230
if let Some(data_type_identifier) = &input_type.data_type_identifier {
139231
detected_generic_keys.append(&mut self.handle_data_type(analysable_data_type.clone(), data_type_identifier.clone()))
140232
} else {
141-
println!("DataTypeIdentifier is undefined!")
233+
error(format!("`{}` uses a definition_data_type_input_types_rule that has a undefined data_type!", data_type.identifier), path.clone());
142234
}
143235
}
144236
}
145237
Config::ReturnType(rule) => {
146238
if let Some(data_type_identifier) = &rule.data_type_identifier {
147239
detected_generic_keys.append(&mut self.handle_data_type(analysable_data_type.clone(), data_type_identifier.clone()))
148240
} else {
149-
println!("DataTypeIdentifier is undefined!")
241+
error(format!("`{}` uses a definition_data_type_return_type_rule that is null!", data_type.identifier), path.clone());
150242
}
151243
}
152244
Config::ParentType(rule) => {
153245
if let Some(data_type_identifier) = &rule.parent_type {
154246
detected_generic_keys.append(&mut self.handle_data_type(analysable_data_type.clone(), data_type_identifier.clone()))
155247
} else {
156-
println!("DataTypeIdentifier is undefined!")
248+
error(format!("`{}` uses a definition_data_type_parent_type_rule that is null!", data_type.identifier), path.clone());
157249
}
158250
}
159251
}
160252
}
161253
}
162254

163-
//TODO: Handle key not present/not exissting
164-
for key in &detected_generic_keys {
165-
println!("Detected key: {}", key);
255+
let defined_but_unused = data_type.generic_keys.iter().filter(|key| !detected_generic_keys.contains(key)).collect::<Vec<&String>>();
256+
let used_but_undefined = detected_generic_keys.iter().filter(|key| !data_type.generic_keys.contains(key)).collect::<Vec<&String>>();
257+
258+
for key in defined_but_unused {
259+
error(format!("`{}` uses a generic_key (`{}`) that's never used!", analysable_data_type.definition_data_type.identifier, key), path.clone());
260+
}
261+
262+
for key in used_but_undefined {
263+
error(format!("`{}` uses a generic_key (`{}`) that's not defined!", analysable_data_type.definition_data_type.identifier, key), path.clone());
166264
}
167265
} else {
168266
// Check here for any empty configs!
169267
for rule in &data_type.rules {
170268
if rule.config.is_none() {
171-
println!("found empty rule!")
269+
error(format!("`{}` uses a rule that is null!", analysable_data_type.definition_data_type.identifier), path.clone());
172270
}
173271
}
174272
}
175273

176274
// Check if at least one Translation is present
177275
if data_type.name.is_empty() {
178-
println!("At least one translation should be defined")
276+
warning(format!("`{}` has no name defined!", analysable_data_type.definition_data_type.identifier), path.clone());
179277
}
180-
181278
}
182279
}

cli/src/command/report.rs

Lines changed: 3 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -12,57 +12,10 @@ pub fn report_errors(path: Option<String>) {
1212
}
1313
};
1414

15-
let mut index = 0;
16-
let collected_data_types = parser
17-
.features
18-
.iter()
19-
.map(|f| f.data_types.clone())
20-
.flatten()
21-
.map(|d| {
22-
index = index + 1;
23-
return AnalysableDataType {
24-
definition_data_type: d.clone(),
25-
id: index
26-
}
27-
})
28-
.collect::<Vec<_>>();
15+
let analyser = Analyser::new(dir_path.as_str());
2916

30-
let collected_functions = parser
31-
.features
32-
.iter()
33-
.map(|f| f.runtime_functions.clone())
34-
.flatten()
35-
.map(|d| {
36-
index = index + 1;
37-
return AnalysableFunction {
38-
function: d.clone(),
39-
id: index
40-
}
41-
})
42-
.collect::<Vec<_>>();
43-
44-
let collected_flow_types = parser
45-
.features
46-
.iter()
47-
.map(|f| f.flow_types.clone())
48-
.flatten()
49-
.map(|d| {
50-
index = index + 1;
51-
return AnalysableFlowType {
52-
flow_type: d.clone(),
53-
id: index
54-
}
55-
})
56-
.collect::<Vec<_>>();
57-
58-
let analyser = Analyser {
59-
data_types: collected_data_types.clone(),
60-
functions: collected_functions,
61-
flow_types: collected_flow_types,
62-
};
63-
64-
for data_type in collected_data_types {
65-
analyser.analyse_data_type(data_type);
17+
for data_type in &analyser.data_types {
18+
analyser.analyse_data_type(data_type.clone());
6619
}
6720

6821
error_table(&parser.features);

0 commit comments

Comments
 (0)