@@ -8,7 +8,7 @@ use std::{
8
8
use anyhow:: Result ;
9
9
use config:: get_compiler_options;
10
10
use css_parser:: { extract_classes, ClassName } ;
11
- use tsx_parser:: { extract_default_css_imports, extract_used_classes} ;
11
+ use tsx_parser:: { extract_default_css_imports, extract_used_classes, UsedClassName } ;
12
12
use utils:: { process_relative_import, replace_aliases} ;
13
13
14
14
mod config;
@@ -71,7 +71,7 @@ fn main() -> Result<()> {
71
71
72
72
let dir = list_files_in_directory ( Path :: new ( "." ) . to_path_buf ( ) , tsconfig. exclude ) ;
73
73
74
- let mut used_classnames: HashMap < String , HashSet < String > > = Default :: default ( ) ;
74
+ let mut used_classnames: HashMap < String , HashSet < UsedClassName > > = Default :: default ( ) ;
75
75
let mut defined_classnames: HashMap < String , HashSet < ClassName > > = Default :: default ( ) ;
76
76
77
77
for entry in & dir {
@@ -85,7 +85,7 @@ fn main() -> Result<()> {
85
85
process_relative_import ( Path :: new ( entry) , & mut style_path) ?;
86
86
replace_aliases ( & mut style_path, tsconfig. compiler_options . paths . clone ( ) ) ;
87
87
88
- let used_fields = extract_used_classes ( & code, & class_names) ;
88
+ let used_fields = extract_used_classes ( & code, & class_names, path . clone ( ) ) ;
89
89
used_classnames
90
90
. entry ( style_path)
91
91
. or_insert_with ( HashSet :: new)
@@ -104,20 +104,22 @@ fn main() -> Result<()> {
104
104
let mut files_count = 0 ;
105
105
let mut errors_count = 0 ;
106
106
107
- for ( css_file, mut classes ) in defined_classnames {
107
+ for ( css_file, mut classes_tsx ) in defined_classnames. clone ( ) {
108
108
if let Some ( used_css) = used_classnames. get ( & css_file) {
109
- classes. retain ( |v| !used_css. contains ( & v. class_name ) ) ;
109
+ let used_css_flatten: Vec < String > =
110
+ used_css. iter ( ) . map ( |v| v. class_name . clone ( ) ) . collect ( ) ;
111
+ classes_tsx. retain ( |v| !used_css_flatten. contains ( & v. class_name ) ) ;
110
112
}
111
113
112
- if classes . is_empty ( ) {
114
+ if classes_tsx . is_empty ( ) {
113
115
continue ;
114
116
}
115
117
116
118
files_count += 1 ;
117
- errors_count += classes . len ( ) ;
119
+ errors_count += classes_tsx . len ( ) ;
118
120
119
121
println ! ( "{}{}{}" , COLOR_BLUE , css_file, COLOR_RESET ) ;
120
- for extra in classes {
122
+ for extra in classes_tsx {
121
123
println ! (
122
124
"{}{}:{} {}Warn{}: Unused class `{}` found" ,
123
125
COLOR_YELLOW ,
@@ -132,6 +134,47 @@ fn main() -> Result<()> {
132
134
println ! ( ) ;
133
135
}
134
136
137
+ let mut undefined_classes: HashMap < String , HashSet < UsedClassName > > = HashMap :: new ( ) ;
138
+
139
+ for ( tsx_file, mut classes) in used_classnames {
140
+ if let Some ( defined_css) = defined_classnames. get ( & tsx_file) {
141
+ let defined_css: HashSet < String > =
142
+ defined_css. iter ( ) . map ( |v| v. class_name . clone ( ) ) . collect ( ) ;
143
+ classes. retain ( |v| !defined_css. contains ( v. class_name . as_str ( ) ) ) ;
144
+ }
145
+
146
+ if classes. is_empty ( ) {
147
+ continue ;
148
+ }
149
+
150
+ files_count += 1 ;
151
+ errors_count += classes. len ( ) ;
152
+
153
+ for extra in classes {
154
+ undefined_classes
155
+ . entry ( extra. file_name . clone ( ) )
156
+ . or_insert_with ( HashSet :: new)
157
+ . insert ( extra) ;
158
+ }
159
+ }
160
+
161
+ for undefined in undefined_classes {
162
+ println ! ( "{}{}{}" , COLOR_BLUE , undefined. 0 , COLOR_RESET ) ;
163
+ for extra in undefined. 1 {
164
+ println ! (
165
+ "{}{}:{} {}Warn{}: Undefined class `{}` used" ,
166
+ COLOR_YELLOW ,
167
+ extra. line,
168
+ extra. column + 1 ,
169
+ COLOR_YELLOW ,
170
+ COLOR_RESET ,
171
+ extra. class_name
172
+ ) ;
173
+ }
174
+
175
+ println ! ( ) ;
176
+ }
177
+
135
178
if errors_count == 0 {
136
179
println ! ( "{}✔{} No CSS lint warnings found" , COLOR_GREEN , COLOR_RESET ) ;
137
180
} else {
0 commit comments