Files
cell/explain.ce
2026-02-16 21:50:39 -06:00

128 lines
3.1 KiB
Plaintext

// 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 tokenize_mod = use('tokenize')
var parse_mod = use('parse')
var fold_mod = use('fold')
var index_mod = use('index')
var explain_mod = use('explain')
var mode = null
var span_arg = null
var symbol_name = null
var file_arg = null
var i = 0
var parts = null
var filename = null
var line = null
var col = null
var src = null
var idx = null
var explain = null
var result = null
var pipeline = {tokenize: tokenize_mod, parse: parse_mod, fold: fold_mod}
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 [file] Find symbol by name")
$stop()
} else if (!starts_with(args[i], '-')) {
if (file_arg == null) {
file_arg = 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()
}
src = text(fd.slurp(filename))
idx = index_mod.index_file(src, filename, pipeline)
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 {
print(json.encode(result, true))
print("\n")
}
}
if (mode == "symbol") {
filename = file_arg
if (filename == null) {
log.error('--symbol requires a file argument')
$stop()
}
if (!fd.is_file(filename)) {
log.error('File not found: ' + filename)
$stop()
}
src = text(fd.slurp(filename))
idx = index_mod.index_file(src, filename, pipeline)
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 {
print(json.encode(result, true))
print("\n")
}
}
$stop()