// cell explain — Query the semantic index for a source file. // // Usage: // cell explain --span file.ce:10:5 Find symbol at position // cell explain --symbol add_node Find symbol by name // cell explain --symbol add_node file.ce Limit to specific file // cell explain --help Show this help var fd = use('fd') var json = use('json') var explain_mod = use('explain') var shop = use('internal/shop') var mode = null var span_arg = null var symbol_name = null var files = [] var i = 0 var parts = null var filename = null var line = null var col = null var idx = null var indexes = [] var explain = null var result = null for (i = 0; i < length(args); i++) { if (args[i] == '--span') { mode = "span" if (i + 1 < length(args)) { span_arg = args[i + 1] i = i + 1 } else { log.error('--span requires file:line:col') $stop() } } else if (args[i] == '--symbol') { mode = "symbol" if (i + 1 < length(args)) { symbol_name = args[i + 1] i = i + 1 } else { log.error('--symbol requires a name') $stop() } } else if (args[i] == '--help' || args[i] == '-h') { log.console("Usage: cell explain [options]") log.console("") log.console("Query the semantic index for a source file.") log.console("") log.console("Options:") log.console(" --span file:line:col Find symbol at position") log.console(" --symbol name ... Find symbol by name across files") $stop() } else if (!starts_with(args[i], '-')) { files[] = args[i] } } if (mode == null) { log.error('Specify --span or --symbol. Use --help for usage.') $stop() } if (mode == "span") { parts = array(span_arg, ":") if (length(parts) < 3) { log.error('--span requires file:line:col format') $stop() } filename = parts[0] line = number(parts[1]) col = number(parts[2]) if (!fd.is_file(filename)) { log.error('File not found: ' + filename) $stop() } idx = shop.index_file(filename) explain = explain_mod.make(idx) result = explain.at_span(line, col) if (result == null) { log.console("Nothing found at " + filename + ":" + text(line) + ":" + text(col)) } else { log.compile(json.encode(result, true)) } } if (mode == "symbol") { if (length(files) == 0) { log.error('--symbol requires at least one file argument') $stop() } // Validate all files exist. i = 0 while (i < length(files)) { if (!fd.is_file(files[i])) { log.error('File not found: ' + files[i]) $stop() } i = i + 1 } if (length(files) == 1) { filename = files[0] idx = shop.index_file(filename) explain = explain_mod.make(idx) result = explain.by_symbol(symbol_name) if (result == null || length(result.symbols) == 0) { log.console("Symbol '" + symbol_name + "' not found in " + filename) } else { log.compile(json.encode(result, true)) } } else if (length(files) > 1) { indexes = [] i = 0 while (i < length(files)) { idx = shop.index_file(files[i]) indexes[] = idx i = i + 1 } result = explain_mod.explain_across(indexes, symbol_name) if (result == null || length(result.symbols) == 0) { log.console("Symbol '" + symbol_name + "' not found in " + text(length(files)) + " files") } else { log.compile(json.encode(result, true)) } } } $stop()