22//! errors.
33
44use std:: {
5- env,
5+ env, fmt,
6+ ops:: AddAssign ,
67 time:: { SystemTime , UNIX_EPOCH } ,
78} ;
89
@@ -118,29 +119,80 @@ impl flags::AnalysisStats {
118119 }
119120
120121 let mut item_tree_sw = self . stop_watch ( ) ;
121- let mut num_item_trees = 0 ;
122122 let source_roots = krates
123123 . iter ( )
124124 . cloned ( )
125125 . map ( |krate| db. file_source_root ( krate. root_file ( db) ) . source_root_id ( db) )
126126 . unique ( ) ;
127+
128+ let mut dep_loc = 0 ;
129+ let mut workspace_loc = 0 ;
130+ let mut dep_item_trees = 0 ;
131+ let mut workspace_item_trees = 0 ;
132+
133+ let mut workspace_item_stats = PrettyItemStats :: default ( ) ;
134+ let mut dep_item_stats = PrettyItemStats :: default ( ) ;
135+
127136 for source_root_id in source_roots {
128137 let source_root = db. source_root ( source_root_id) . source_root ( db) ;
129- if !source_root. is_library || self . with_deps {
130- for file_id in source_root. iter ( ) {
131- if let Some ( p) = source_root. path_for_file ( & file_id) {
132- if let Some ( ( _, Some ( "rs" ) ) ) = p. name_and_extension ( ) {
133- db. file_item_tree ( EditionedFileId :: current_edition ( file_id) . into ( ) ) ;
134- num_item_trees += 1 ;
138+ for file_id in source_root. iter ( ) {
139+ if let Some ( p) = source_root. path_for_file ( & file_id) {
140+ if let Some ( ( _, Some ( "rs" ) ) ) = p. name_and_extension ( ) {
141+ // measure workspace/project code
142+ if !source_root. is_library || self . with_deps {
143+ let length = db. file_text ( file_id) . text ( db) . lines ( ) . count ( ) ;
144+ let item_stats = db
145+ . file_item_tree ( EditionedFileId :: current_edition ( file_id) . into ( ) )
146+ . item_tree_stats ( )
147+ . into ( ) ;
148+
149+ workspace_loc += length;
150+ workspace_item_trees += 1 ;
151+ workspace_item_stats += item_stats;
152+ } else {
153+ let length = db. file_text ( file_id) . text ( db) . lines ( ) . count ( ) ;
154+ let item_stats = db
155+ . file_item_tree ( EditionedFileId :: current_edition ( file_id) . into ( ) )
156+ . item_tree_stats ( )
157+ . into ( ) ;
158+
159+ dep_loc += length;
160+ dep_item_trees += 1 ;
161+ dep_item_stats += item_stats;
135162 }
136163 }
137164 }
138165 }
139166 }
140- eprintln ! ( " item trees: {num_item_trees }" ) ;
167+ eprintln ! ( " item trees: {workspace_item_trees }" ) ;
141168 let item_tree_time = item_tree_sw. elapsed ( ) ;
169+
170+ eprintln ! (
171+ " dependency lines of code: {}, item trees: {}" ,
172+ UsizeWithUnderscore ( dep_loc) ,
173+ UsizeWithUnderscore ( dep_item_trees) ,
174+ ) ;
175+ eprintln ! ( " dependency item stats: {}" , dep_item_stats) ;
176+
177+ // FIXME(salsa-transition): bring back stats for ParseQuery (file size)
178+ // and ParseMacroExpansionQuery (macro expansion "file") size whenever we implement
179+ // Salsa's memory usage tracking works with tracked functions.
180+
181+ // let mut total_file_size = Bytes::default();
182+ // for e in ide_db::base_db::ParseQuery.in_db(db).entries::<Vec<_>>() {
183+ // total_file_size += syntax_len(db.parse(e.key).syntax_node())
184+ // }
185+
186+ // let mut total_macro_file_size = Bytes::default();
187+ // for e in hir::db::ParseMacroExpansionQuery.in_db(db).entries::<Vec<_>>() {
188+ // let val = db.parse_macro_expansion(e.key).value.0;
189+ // total_macro_file_size += syntax_len(val.syntax_node())
190+ // }
191+ // eprintln!("source files: {total_file_size}, macro files: {total_macro_file_size}");
192+
142193 eprintln ! ( "{:<20} {}" , "Item Tree Collection:" , item_tree_time) ;
143194 report_metric ( "item tree time" , item_tree_time. time . as_millis ( ) as u64 , "ms" ) ;
195+ eprintln ! ( " Total Statistics:" ) ;
144196
145197 let mut crate_def_map_sw = self . stop_watch ( ) ;
146198 let mut num_crates = 0 ;
@@ -163,11 +215,16 @@ impl flags::AnalysisStats {
163215 shuffle ( & mut rng, & mut visit_queue) ;
164216 }
165217
166- eprint ! ( " crates: {num_crates}" ) ;
218+ eprint ! ( " crates: {num_crates}" ) ;
167219 let mut num_decls = 0 ;
168220 let mut bodies = Vec :: new ( ) ;
169221 let mut adts = Vec :: new ( ) ;
170222 let mut file_ids = Vec :: new ( ) ;
223+
224+ let mut num_traits = 0 ;
225+ let mut num_macro_rules_macros = 0 ;
226+ let mut num_proc_macros = 0 ;
227+
171228 while let Some ( module) = visit_queue. pop ( ) {
172229 if visited_modules. insert ( module) {
173230 file_ids. extend ( module. as_source_file_id ( db) ) ;
@@ -189,6 +246,14 @@ impl flags::AnalysisStats {
189246 bodies. push ( DefWithBody :: from ( c) ) ;
190247 }
191248 ModuleDef :: Static ( s) => bodies. push ( DefWithBody :: from ( s) ) ,
249+ ModuleDef :: Trait ( _) => num_traits += 1 ,
250+ ModuleDef :: Macro ( m) => match m. kind ( db) {
251+ hir:: MacroKind :: Declarative => num_macro_rules_macros += 1 ,
252+ hir:: MacroKind :: Derive
253+ | hir:: MacroKind :: Attr
254+ | hir:: MacroKind :: ProcMacro => num_proc_macros += 1 ,
255+ _ => ( ) ,
256+ } ,
192257 _ => ( ) ,
193258 } ;
194259 }
@@ -217,6 +282,26 @@ impl flags::AnalysisStats {
217282 . filter( |it| matches!( it, DefWithBody :: Const ( _) | DefWithBody :: Static ( _) ) )
218283 . count( ) ,
219284 ) ;
285+
286+ eprintln ! ( " Workspace:" ) ;
287+ eprintln ! (
288+ " traits: {num_traits}, macro_rules macros: {num_macro_rules_macros}, proc_macros: {num_proc_macros}"
289+ ) ;
290+ eprintln ! (
291+ " lines of code: {}, item trees: {}" ,
292+ UsizeWithUnderscore ( workspace_loc) ,
293+ UsizeWithUnderscore ( workspace_item_trees) ,
294+ ) ;
295+ eprintln ! ( " usages: {}" , workspace_item_stats) ;
296+
297+ eprintln ! ( " Dependencies:" ) ;
298+ eprintln ! (
299+ " lines of code: {}, item trees: {}" ,
300+ UsizeWithUnderscore ( dep_loc) ,
301+ UsizeWithUnderscore ( dep_item_trees) ,
302+ ) ;
303+ eprintln ! ( " declarations: {}" , dep_item_stats) ;
304+
220305 let crate_def_map_time = crate_def_map_sw. elapsed ( ) ;
221306 eprintln ! ( "{:<20} {}" , "Item Collection:" , crate_def_map_time) ;
222307 report_metric ( "crate def map time" , crate_def_map_time. time . as_millis ( ) as u64 , "ms" ) ;
@@ -264,24 +349,6 @@ impl flags::AnalysisStats {
264349 }
265350 report_metric ( "total memory" , total_span. memory . allocated . megabytes ( ) as u64 , "MB" ) ;
266351
267- if self . source_stats {
268- // FIXME(salsa-transition): bring back stats for ParseQuery (file size)
269- // and ParseMacroExpansionQuery (mcaro expansion "file") size whenever we implement
270- // Salsa's memory usage tracking works with tracked functions.
271-
272- // let mut total_file_size = Bytes::default();
273- // for e in ide_db::base_db::ParseQuery.in_db(db).entries::<Vec<_>>() {
274- // total_file_size += syntax_len(db.parse(e.key).syntax_node())
275- // }
276-
277- // let mut total_macro_file_size = Bytes::default();
278- // for e in hir::db::ParseMacroExpansionQuery.in_db(db).entries::<Vec<_>>() {
279- // let val = db.parse_macro_expansion(e.key).value.0;
280- // total_macro_file_size += syntax_len(val.syntax_node())
281- // }
282- // eprintln!("source files: {total_file_size}, macro files: {total_macro_file_size}");
283- }
284-
285352 if verbosity. is_verbose ( ) {
286353 print_memory_usage ( host, vfs) ;
287354 }
@@ -1217,6 +1284,78 @@ fn percentage(n: u64, total: u64) -> u64 {
12171284 ( n * 100 ) . checked_div ( total) . unwrap_or ( 100 )
12181285}
12191286
1287+ #[ derive( Default , Debug , Eq , PartialEq ) ]
1288+ struct UsizeWithUnderscore ( usize ) ;
1289+
1290+ impl fmt:: Display for UsizeWithUnderscore {
1291+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1292+ let num_str = self . 0 . to_string ( ) ;
1293+
1294+ if num_str. len ( ) <= 3 {
1295+ return write ! ( f, "{}" , num_str) ;
1296+ }
1297+
1298+ let mut result = String :: new ( ) ;
1299+
1300+ for ( count, ch) in num_str. chars ( ) . rev ( ) . enumerate ( ) {
1301+ if count > 0 && count % 3 == 0 {
1302+ result. push ( '_' ) ;
1303+ }
1304+ result. push ( ch) ;
1305+ }
1306+
1307+ let result = result. chars ( ) . rev ( ) . collect :: < String > ( ) ;
1308+ write ! ( f, "{}" , result)
1309+ }
1310+ }
1311+
1312+ impl std:: ops:: AddAssign for UsizeWithUnderscore {
1313+ fn add_assign ( & mut self , other : UsizeWithUnderscore ) {
1314+ self . 0 += other. 0 ;
1315+ }
1316+ }
1317+
1318+ #[ derive( Default , Debug , Eq , PartialEq ) ]
1319+ struct PrettyItemStats {
1320+ traits : UsizeWithUnderscore ,
1321+ impls : UsizeWithUnderscore ,
1322+ mods : UsizeWithUnderscore ,
1323+ macro_calls : UsizeWithUnderscore ,
1324+ macro_rules : UsizeWithUnderscore ,
1325+ }
1326+
1327+ impl From < hir_def:: item_tree:: ItemTreeDataStats > for PrettyItemStats {
1328+ fn from ( value : hir_def:: item_tree:: ItemTreeDataStats ) -> Self {
1329+ Self {
1330+ traits : UsizeWithUnderscore ( value. traits ) ,
1331+ impls : UsizeWithUnderscore ( value. impls ) ,
1332+ mods : UsizeWithUnderscore ( value. mods ) ,
1333+ macro_calls : UsizeWithUnderscore ( value. macro_calls ) ,
1334+ macro_rules : UsizeWithUnderscore ( value. macro_rules ) ,
1335+ }
1336+ }
1337+ }
1338+
1339+ impl AddAssign for PrettyItemStats {
1340+ fn add_assign ( & mut self , rhs : Self ) {
1341+ self . traits += rhs. traits ;
1342+ self . impls += rhs. impls ;
1343+ self . mods += rhs. mods ;
1344+ self . macro_calls += rhs. macro_calls ;
1345+ self . macro_rules += rhs. macro_rules ;
1346+ }
1347+ }
1348+
1349+ impl fmt:: Display for PrettyItemStats {
1350+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1351+ write ! (
1352+ f,
1353+ "traits: {}, impl: {}, mods: {}, macro calls: {}, macro rules: {}" ,
1354+ self . traits, self . impls, self . mods, self . macro_calls, self . macro_rules
1355+ )
1356+ }
1357+ }
1358+
12201359// FIXME(salsa-transition): bring this back whenever we implement
12211360// Salsa's memory usage tracking to work with tracked functions.
12221361// fn syntax_len(node: SyntaxNode) -> usize {
0 commit comments