Skip to content

Commit a723810

Browse files
Merge pull request #51 from code0-tech/49-poc-definition-analysis
Definition Linter
2 parents 84a2e71 + 9cd1b7c commit a723810

File tree

156 files changed

+10253
-10581
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

156 files changed

+10253
-10581
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
*.DS_Store
33
**/node_modules
44
.idea
5-
reader/ts/src/*.js
5+
reader/ts/src/*.js
6+
reader/ts/build

cli/src/analyser/diagnostics.rs

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
use crate::formatter::{error, warning};
2+
use code0_definition_reader::reader::Meta;
3+
use std::cmp::PartialEq;
4+
use std::path::Path;
5+
use std::process::exit;
6+
7+
#[derive(Default)]
8+
pub struct Reporter {
9+
diagnose: Vec<Diagnose>,
10+
}
11+
12+
impl PartialEq for Severity {
13+
fn eq(&self, other: &Self) -> bool {
14+
match self {
15+
Severity::Error => {
16+
if let Severity::Error = other {
17+
return true;
18+
}
19+
false
20+
}
21+
Severity::Warning => {
22+
if let Severity::Warning = other {
23+
return true;
24+
}
25+
false
26+
}
27+
Severity::Debug => {
28+
if let Severity::Debug = other {
29+
return true;
30+
}
31+
false
32+
}
33+
}
34+
}
35+
}
36+
37+
impl Reporter {
38+
pub fn add_report(&mut self, diagnose: Diagnose) {
39+
self.diagnose.push(diagnose);
40+
}
41+
42+
pub fn run_report(&self, will_exit: bool) {
43+
for error in &self.get_errors() {
44+
println!("{}", error.print());
45+
}
46+
47+
for warning in &self.get_warnings() {
48+
println!("{}", warning.print());
49+
}
50+
51+
if !self.get_errors().is_empty() && will_exit {
52+
exit(1)
53+
}
54+
}
55+
56+
pub fn get_errors(&self) -> Vec<&Diagnose> {
57+
self.diagnose
58+
.iter()
59+
.filter(|p| p.kind.severity() == Severity::Error)
60+
.collect()
61+
}
62+
63+
pub fn get_warnings(&self) -> Vec<&Diagnose> {
64+
self.diagnose
65+
.iter()
66+
.filter(|p| p.kind.severity() == Severity::Warning)
67+
.collect()
68+
}
69+
70+
pub fn get_debug(&self) -> Vec<&Diagnose> {
71+
self.diagnose
72+
.iter()
73+
.filter(|p| p.kind.severity() == Severity::Debug)
74+
.collect()
75+
}
76+
}
77+
78+
pub enum Severity {
79+
Error,
80+
Warning,
81+
Debug,
82+
}
83+
84+
pub struct Diagnose {
85+
kind: DiagnosticKind,
86+
definition_name: String,
87+
definition: Meta,
88+
}
89+
90+
pub enum DiagnosticKind {
91+
DeserializationError { description: String },
92+
DuplicateDataTypeIdentifier { identifier: String },
93+
DuplicateFlowTypeIdentifier { identifier: String },
94+
DuplicateRuntimeFunctionIdentifier { identifier: String },
95+
DuplicateRuntimeParameterIdentifier { identifier: String },
96+
UndefinedDataTypeIdentifier { identifier: String },
97+
EmptyGenericMapper,
98+
GenericKeyNotInMappingTarget { key: String, target: String },
99+
NullField { field_name: String },
100+
ForbiddenVariant,
101+
UnusedGenericKey { key: String },
102+
UndefinedGenericKey { key: String },
103+
UndefinedTranslation { translation_field: String },
104+
}
105+
106+
impl DiagnosticKind {
107+
pub fn severity(&self) -> Severity {
108+
use DiagnosticKind::*;
109+
match self {
110+
DeserializationError { .. }
111+
| DuplicateDataTypeIdentifier { .. }
112+
| DuplicateFlowTypeIdentifier { .. }
113+
| DuplicateRuntimeFunctionIdentifier { .. }
114+
| DuplicateRuntimeParameterIdentifier { .. }
115+
| GenericKeyNotInMappingTarget { .. }
116+
| EmptyGenericMapper
117+
| UndefinedDataTypeIdentifier { .. }
118+
| NullField { .. }
119+
| ForbiddenVariant
120+
| UnusedGenericKey { .. }
121+
| UndefinedGenericKey { .. } => Severity::Error,
122+
UndefinedTranslation { .. } => Severity::Warning,
123+
}
124+
}
125+
}
126+
127+
impl Diagnose {
128+
pub fn new(definition_name: String, definition: Meta, kind: DiagnosticKind) -> Self {
129+
Self {
130+
definition_name,
131+
definition,
132+
kind,
133+
}
134+
}
135+
136+
pub fn print(&self) -> String {
137+
let path = format!(
138+
"{}:{}:{}",
139+
Path::new(&self.definition.path.clone()).display(),
140+
1,
141+
1
142+
);
143+
144+
use DiagnosticKind::*;
145+
match &self.kind {
146+
EmptyGenericMapper => error(
147+
format!(
148+
"`{}` defined a generic_type but its mapper are empty!`",
149+
self.definition_name
150+
),
151+
&path,
152+
),
153+
DeserializationError { description } => error(
154+
format!("A JSON paring error occurred: `{}`", description),
155+
&path,
156+
),
157+
GenericKeyNotInMappingTarget { key, target } => error(
158+
format!(
159+
"`{}` is mapping the key: {} onto the target: {}. But the target did not define this generic_key!",
160+
self.definition_name, key, target
161+
),
162+
&path,
163+
),
164+
DuplicateDataTypeIdentifier { identifier } => error(
165+
format!(
166+
"The data_type `{}` is already defined resulting in a duplicate!",
167+
identifier
168+
),
169+
&path,
170+
),
171+
DuplicateFlowTypeIdentifier { identifier } => error(
172+
format!(
173+
"The flow_type `{}` is already defined resulting in a duplicate!",
174+
identifier
175+
),
176+
&path,
177+
),
178+
DuplicateRuntimeFunctionIdentifier { identifier } => error(
179+
format!(
180+
"The runtime_function `{}` is already defined resulting in a duplicate!",
181+
identifier
182+
),
183+
&path,
184+
),
185+
DuplicateRuntimeParameterIdentifier { identifier } => error(
186+
format!(
187+
"The runtime_parameter `{}` is already defined resulting in a duplicate!",
188+
identifier
189+
),
190+
&path,
191+
),
192+
UndefinedDataTypeIdentifier { identifier } => error(
193+
format!(
194+
"`{}` uses an undefined data_type_identifier: `{}`!",
195+
self.definition_name, identifier
196+
),
197+
&path,
198+
),
199+
NullField { field_name } => error(
200+
format!(
201+
"`{}` has a field (`{}`) that is null!",
202+
self.definition_name, field_name
203+
),
204+
&path,
205+
),
206+
ForbiddenVariant => error(
207+
format!(
208+
"The data_type variant of `{}` is 0 and thus incorrect!",
209+
self.definition_name
210+
),
211+
&path,
212+
),
213+
UnusedGenericKey { key } => error(
214+
format!(
215+
"`{}` defined a generic_key (`{}`) that is never used!",
216+
self.definition_name, key
217+
),
218+
&path,
219+
),
220+
UndefinedGenericKey { key } => error(
221+
format!(
222+
"`{}` uses a generic_key (`{}`) that's not defined!",
223+
self.definition_name, key
224+
),
225+
&path,
226+
),
227+
UndefinedTranslation { translation_field } => warning(
228+
format!(
229+
"`{}` has an empty field (`{}`) of translations!",
230+
self.definition_name, translation_field
231+
),
232+
&path,
233+
),
234+
}
235+
}
236+
}

0 commit comments

Comments
 (0)