@@ -62,6 +62,29 @@ enum TraceDirection {
6262 Reverse ,
6363}
6464
65+ #[ derive( Clone , Copy , Debug , Eq , PartialEq , ValueEnum ) ]
66+ enum OriginTerminalFilter {
67+ Network ,
68+ Persistence ,
69+ Cache ,
70+ Event ,
71+ Keychain ,
72+ Search ,
73+ }
74+
75+ impl OriginTerminalFilter {
76+ const fn as_str ( self ) -> & ' static str {
77+ match self {
78+ Self :: Network => "network" ,
79+ Self :: Persistence => "persistence" ,
80+ Self :: Cache => "cache" ,
81+ Self :: Event => "event" ,
82+ Self :: Keychain => "keychain" ,
83+ Self :: Search => "search" ,
84+ }
85+ }
86+ }
87+
6588#[ derive( Subcommand ) ]
6689enum Commands {
6790 /// Analyze source files and output graph
@@ -168,7 +191,7 @@ enum SymbolCommands {
168191 /// Include source snippet and relationships in results
169192 #[ arg( long) ]
170193 context : bool ,
171- /// Fields to display (comma-separated: file,id,module,span,snippet,visibility,signature,role; or "all"/"none")
194+ /// Fields to display (comma-separated: file,id,module,span,snippet,visibility,signature,role; or "full"/" all"/"none")
172195 #[ arg( long) ]
173196 fields : Option < String > ,
174197 } ,
@@ -182,7 +205,7 @@ enum SymbolCommands {
182205 /// Output format
183206 #[ arg( long, value_enum, default_value_t = QueryOutputFormat :: Json ) ]
184207 format : QueryOutputFormat ,
185- /// Fields to display (comma-separated: file,id,module,span,snippet,visibility,signature,role; or "all"/"none")
208+ /// Fields to display (comma-separated: file,id,module,span,snippet,visibility,signature,role; or "full"/" all"/"none")
186209 #[ arg( long) ]
187210 fields : Option < String > ,
188211 } ,
@@ -199,7 +222,7 @@ enum SymbolCommands {
199222 /// Output format
200223 #[ arg( long, value_enum, default_value_t = QueryOutputFormat :: Json ) ]
201224 format : QueryOutputFormat ,
202- /// Fields to display (comma-separated: file,id,module,span,snippet,visibility,signature,role; or "all"/"none")
225+ /// Fields to display (comma-separated: file,id,module,span,snippet,visibility,signature,role; or "full"/" all"/"none")
203226 #[ arg( long) ]
204227 fields : Option < String > ,
205228 } ,
@@ -239,6 +262,9 @@ enum FlowCommands {
239262 /// Output format
240263 #[ arg( long, value_enum, default_value_t = QueryOutputFormat :: Json ) ]
241264 format : QueryOutputFormat ,
265+ /// Fields to display in tree output (comma-separated: file; or "full"/"all"/"none")
266+ #[ arg( long) ]
267+ fields : Option < String > ,
242268 } ,
243269 /// Derive a semantic effect graph from a symbol
244270 Graph {
@@ -253,6 +279,9 @@ enum FlowCommands {
253279 /// Output format
254280 #[ arg( long, value_enum, default_value_t = QueryOutputFormat :: Json ) ]
255281 format : QueryOutputFormat ,
282+ /// Fields to display in tree output (comma-separated: file; or "full"/"all"/"none")
283+ #[ arg( long) ]
284+ fields : Option < String > ,
256285 } ,
257286 /// Trace backward to likely API/data origins for a UI symbol
258287 Origin {
@@ -261,12 +290,18 @@ enum FlowCommands {
261290 /// Maximum traversal depth
262291 #[ arg( long, default_value = "10" ) ]
263292 depth : usize ,
293+ /// Keep only origins whose terminal kind matches
294+ #[ arg( long, value_enum) ]
295+ terminal_kind : Option < OriginTerminalFilter > ,
264296 /// Project directory
265297 #[ arg( short, long, default_value = "." ) ]
266298 path : PathBuf ,
267299 /// Output format
268300 #[ arg( long, value_enum, default_value_t = QueryOutputFormat :: Json ) ]
269301 format : QueryOutputFormat ,
302+ /// Fields to display in output (comma-separated: file,snippet; or "full"/"all"/"none")
303+ #[ arg( long) ]
304+ fields : Option < String > ,
270305 } ,
271306 /// List auto-detected entry points
272307 Entries {
@@ -276,6 +311,9 @@ enum FlowCommands {
276311 /// Output format
277312 #[ arg( long, value_enum, default_value_t = QueryOutputFormat :: Json ) ]
278313 format : QueryOutputFormat ,
314+ /// Fields to display in tree output (comma-separated: file; or "full"/"all"/"none")
315+ #[ arg( long) ]
316+ fields : Option < String > ,
279317 } ,
280318}
281319
@@ -291,6 +329,9 @@ enum L10nCommands {
291329 /// Output format
292330 #[ arg( long, value_enum, default_value_t = QueryOutputFormat :: Json ) ]
293331 format : QueryOutputFormat ,
332+ /// Fields to display in tree output (comma-separated: file; or "full"/"all"/"none")
333+ #[ arg( long) ]
334+ fields : Option < String > ,
294335 } ,
295336 /// Find SwiftUI usage sites for a localization key
296337 Usages {
@@ -305,6 +346,9 @@ enum L10nCommands {
305346 /// Output format
306347 #[ arg( long, value_enum, default_value_t = QueryOutputFormat :: Json ) ]
307348 format : QueryOutputFormat ,
349+ /// Fields to display in tree output (comma-separated: file; or "full"/"all"/"none")
350+ #[ arg( long) ]
351+ fields : Option < String > ,
308352 } ,
309353}
310354
@@ -329,6 +373,9 @@ enum AssetCommands {
329373 /// Output format
330374 #[ arg( long, value_enum, default_value_t = QueryOutputFormat :: Json ) ]
331375 format : QueryOutputFormat ,
376+ /// Fields to display in tree output (comma-separated: file; or "full"/"all"/"none")
377+ #[ arg( long) ]
378+ fields : Option < String > ,
332379 } ,
333380}
334381
@@ -529,7 +576,8 @@ fn run_pipeline(
529576 let line_idx = snippet:: LineIndex :: new ( & source_str) ;
530577 for node in & mut result. nodes {
531578 if snippet:: should_extract_snippet ( node. kind ) {
532- node. snippet = line_idx. extract_full_snippet ( & node. span ) ;
579+ node. snippet = line_idx
580+ . extract_symbol_snippet ( & node. span , & node. name , node. kind ) ;
533581 }
534582 }
535583 }
@@ -754,6 +802,13 @@ fn resolve_field_set(fields_flag: &Option<String>, path: &Path) -> fields::Field
754802 }
755803}
756804
805+ fn resolve_search_field_set ( fields_flag : & Option < String > , path : & Path ) -> fields:: FieldSet {
806+ match fields_flag {
807+ Some ( _) => resolve_field_set ( fields_flag, path) ,
808+ None => resolve_field_set ( fields_flag, path) . with_id ( ) ,
809+ }
810+ }
811+
757812fn tree_render_options ( color : ColorMode ) -> render:: RenderOptions {
758813 use std:: io:: IsTerminal ;
759814
@@ -1033,7 +1088,7 @@ fn handle_symbol_command(
10331088 context,
10341089 fields,
10351090 } => {
1036- let field_set = resolve_field_set ( & fields, & path) ;
1091+ let field_set = resolve_search_field_set ( & fields, & path) ;
10371092 let index = open_search_index ( & path) ?;
10381093 let options = search:: SearchOptions {
10391094 kind,
@@ -1123,57 +1178,89 @@ fn handle_flow_command(
11231178 depth,
11241179 path,
11251180 format,
1181+ fields,
11261182 } => match direction {
1127- TraceDirection :: Forward => handle_resolved_graph_query (
1128- & path,
1129- format,
1130- render_options,
1131- "symbol" ,
1132- |graph| query:: trace:: query_trace ( graph, & symbol, depth. unwrap_or ( 10 ) ) ,
1133- render:: render_trace_with_options,
1134- ) ,
1135- TraceDirection :: Reverse => handle_resolved_graph_query (
1136- & path,
1137- format,
1138- render_options,
1139- "symbol" ,
1140- |graph| query:: reverse:: query_reverse ( graph, & symbol, depth) ,
1141- render:: render_reverse_with_options,
1142- ) ,
1183+ TraceDirection :: Forward => {
1184+ let render_options = render_options. with_fields ( resolve_field_set ( & fields, & path) ) ;
1185+ handle_resolved_graph_query (
1186+ & path,
1187+ format,
1188+ render_options,
1189+ "symbol" ,
1190+ |graph| query:: trace:: query_trace ( graph, & symbol, depth. unwrap_or ( 10 ) ) ,
1191+ render:: render_trace_with_options,
1192+ )
1193+ }
1194+ TraceDirection :: Reverse => {
1195+ let render_options = render_options. with_fields ( resolve_field_set ( & fields, & path) ) ;
1196+ handle_resolved_graph_query (
1197+ & path,
1198+ format,
1199+ render_options,
1200+ "symbol" ,
1201+ |graph| query:: reverse:: query_reverse ( graph, & symbol, depth) ,
1202+ render:: render_reverse_with_options,
1203+ )
1204+ }
11431205 } ,
11441206 FlowCommands :: Graph {
11451207 symbol,
11461208 depth,
11471209 path,
11481210 format,
1149- } => handle_resolved_graph_query (
1150- & path,
1151- format,
1152- render_options,
1153- "symbol" ,
1154- |graph| query:: dataflow:: query_dataflow ( graph, & symbol, depth) ,
1155- render:: render_dataflow_with_options,
1156- ) ,
1211+ fields,
1212+ } => {
1213+ let render_options = render_options. with_fields ( resolve_field_set ( & fields, & path) ) ;
1214+ handle_resolved_graph_query (
1215+ & path,
1216+ format,
1217+ render_options,
1218+ "symbol" ,
1219+ |graph| query:: dataflow:: query_dataflow ( graph, & symbol, depth) ,
1220+ render:: render_dataflow_with_options,
1221+ )
1222+ }
11571223 FlowCommands :: Origin {
11581224 symbol,
11591225 depth,
1226+ terminal_kind,
11601227 path,
11611228 format,
1162- } => handle_resolved_graph_query (
1163- & path,
1164- format,
1165- render_options,
1166- "symbol" ,
1167- |graph| query:: origin:: query_origin ( graph, & symbol, depth) ,
1168- render:: render_origin_with_options,
1169- ) ,
1170- FlowCommands :: Entries { path, format } => handle_graph_query (
1171- & path,
1229+ fields,
1230+ } => {
1231+ let field_set = resolve_field_set ( & fields, & path) ;
1232+ let render_options = render_options. with_fields ( field_set) ;
1233+ handle_resolved_graph_query (
1234+ & path,
1235+ format,
1236+ render_options,
1237+ "symbol" ,
1238+ |graph| {
1239+ let result =
1240+ query:: origin:: query_origin_with_path ( graph, & symbol, depth, Some ( & path) ) ?;
1241+ let result = query:: origin:: filter_origin_result_by_terminal_kind (
1242+ result,
1243+ terminal_kind. map ( OriginTerminalFilter :: as_str) ,
1244+ ) ;
1245+ Ok ( query:: origin:: project_origin_result ( result, field_set) )
1246+ } ,
1247+ render:: render_origin_with_options,
1248+ )
1249+ }
1250+ FlowCommands :: Entries {
1251+ path,
11721252 format,
1173- render_options,
1174- query:: entries:: query_entries,
1175- render:: render_entries_with_options,
1176- ) ,
1253+ fields,
1254+ } => {
1255+ let render_options = render_options. with_fields ( resolve_field_set ( & fields, & path) ) ;
1256+ handle_graph_query (
1257+ & path,
1258+ format,
1259+ render_options,
1260+ query:: entries:: query_entries,
1261+ render:: render_entries_with_options,
1262+ )
1263+ }
11771264 }
11781265}
11791266
@@ -1186,7 +1273,9 @@ fn handle_l10n_command(
11861273 symbol,
11871274 path,
11881275 format,
1276+ fields,
11891277 } => {
1278+ let render_options = render_options. with_fields ( resolve_field_set ( & fields, & path) ) ;
11901279 let graph = load_graph ( & path) ?;
11911280 let catalogs = localization:: load_catalog_index ( & path) ?;
11921281 let result = resolve_query_result (
@@ -1205,7 +1294,9 @@ fn handle_l10n_command(
12051294 table,
12061295 path,
12071296 format,
1297+ fields,
12081298 } => {
1299+ let render_options = render_options. with_fields ( resolve_field_set ( & fields, & path) ) ;
12091300 let graph = load_graph ( & path) ?;
12101301 let catalogs = localization:: load_catalog_index ( & path) ?;
12111302 let result = query:: usages:: query_usages ( & graph, & catalogs, & key, table. as_deref ( ) ) ;
@@ -1219,7 +1310,10 @@ fn handle_l10n_command(
12191310 }
12201311}
12211312
1222- fn handle_asset_command ( command : AssetCommands ) -> anyhow:: Result < ( ) > {
1313+ fn handle_asset_command (
1314+ command : AssetCommands ,
1315+ render_options : render:: RenderOptions ,
1316+ ) -> anyhow:: Result < ( ) > {
12231317 match command {
12241318 AssetCommands :: List { unused, path } => {
12251319 if unused {
@@ -1233,7 +1327,13 @@ fn handle_asset_command(command: AssetCommands) -> anyhow::Result<()> {
12331327 print_json ( & records)
12341328 }
12351329 }
1236- AssetCommands :: Usages { name, path, format } => {
1330+ AssetCommands :: Usages {
1331+ name,
1332+ path,
1333+ format,
1334+ fields,
1335+ } => {
1336+ let render_options = render_options. with_fields ( resolve_field_set ( & fields, & path) ) ;
12371337 let graph = load_graph ( & path) ?;
12381338 let usages = assets:: find_usages ( & graph, & name) ;
12391339 match format {
@@ -1243,10 +1343,12 @@ fn handle_asset_command(command: AssetCommands) -> anyhow::Result<()> {
12431343 eprintln ! ( " no usages found for asset '{name}'" ) ;
12441344 } else {
12451345 for usage in & usages {
1246- println ! (
1247- " {} ({}) — {}" ,
1248- usage. node_name, usage. file, usage. asset_name
1249- ) ;
1346+ let file_label = if render_options. fields . file {
1347+ format ! ( " ({})" , usage. file)
1348+ } else {
1349+ String :: new ( )
1350+ } ;
1351+ println ! ( " {}{} — {}" , usage. node_name, file_label, usage. asset_name) ;
12501352 }
12511353 }
12521354 Ok ( ( ) )
@@ -1412,7 +1514,7 @@ fn main() -> anyhow::Result<()> {
14121514 Commands :: Symbol { command } => handle_symbol_command ( command, render_options) ?,
14131515 Commands :: Flow { command } => handle_flow_command ( command, render_options) ?,
14141516 Commands :: L10n { command } => handle_l10n_command ( command, render_options) ?,
1415- Commands :: Asset { command } => handle_asset_command ( command) ?,
1517+ Commands :: Asset { command } => handle_asset_command ( command, render_options ) ?,
14161518 Commands :: Repo { command } => handle_repo_command ( command) ?,
14171519 }
14181520
0 commit comments