@@ -8,7 +8,7 @@ use std::{
88use anyhow:: Result ;
99use config:: get_compiler_options;
1010use 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 } ;
1212use utils:: { process_relative_import, replace_aliases} ;
1313
1414mod config;
@@ -71,7 +71,7 @@ fn main() -> Result<()> {
7171
7272 let dir = list_files_in_directory ( Path :: new ( "." ) . to_path_buf ( ) , tsconfig. exclude ) ;
7373
74- let mut used_classnames: HashMap < String , HashSet < String > > = Default :: default ( ) ;
74+ let mut used_classnames: HashMap < String , HashSet < UsedClassName > > = Default :: default ( ) ;
7575 let mut defined_classnames: HashMap < String , HashSet < ClassName > > = Default :: default ( ) ;
7676
7777 for entry in & dir {
@@ -85,7 +85,7 @@ fn main() -> Result<()> {
8585 process_relative_import ( Path :: new ( entry) , & mut style_path) ?;
8686 replace_aliases ( & mut style_path, tsconfig. compiler_options . paths . clone ( ) ) ;
8787
88- let used_fields = extract_used_classes ( & code, & class_names) ;
88+ let used_fields = extract_used_classes ( & code, & class_names, path . clone ( ) ) ;
8989 used_classnames
9090 . entry ( style_path)
9191 . or_insert_with ( HashSet :: new)
@@ -104,20 +104,22 @@ fn main() -> Result<()> {
104104 let mut files_count = 0 ;
105105 let mut errors_count = 0 ;
106106
107- for ( css_file, mut classes ) in defined_classnames {
107+ for ( css_file, mut classes_tsx ) in defined_classnames. clone ( ) {
108108 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 ) ) ;
110112 }
111113
112- if classes . is_empty ( ) {
114+ if classes_tsx . is_empty ( ) {
113115 continue ;
114116 }
115117
116118 files_count += 1 ;
117- errors_count += classes . len ( ) ;
119+ errors_count += classes_tsx . len ( ) ;
118120
119121 println ! ( "{}{}{}" , COLOR_BLUE , css_file, COLOR_RESET ) ;
120- for extra in classes {
122+ for extra in classes_tsx {
121123 println ! (
122124 "{}{}:{} {}Warn{}: Unused class `{}` found" ,
123125 COLOR_YELLOW ,
@@ -132,6 +134,47 @@ fn main() -> Result<()> {
132134 println ! ( ) ;
133135 }
134136
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+
135178 if errors_count == 0 {
136179 println ! ( "{}✔{} No CSS lint warnings found" , COLOR_GREEN , COLOR_RESET ) ;
137180 } else {
0 commit comments