improved semantic indexing
This commit is contained in:
93
explain.ce
93
explain.ce
@@ -13,11 +13,35 @@ var parse_mod = use('parse')
|
||||
var fold_mod = use('fold')
|
||||
var index_mod = use('index')
|
||||
var explain_mod = use('explain')
|
||||
var shop = use('internal/shop')
|
||||
|
||||
// Resolve import paths on an index in-place.
|
||||
var resolve_imports = function(idx_obj, fname) {
|
||||
var fi = shop.file_info(fd.realpath(fname))
|
||||
var ctx = fi.package
|
||||
var ri = 0
|
||||
var rp = null
|
||||
var lp = null
|
||||
while (ri < length(idx_obj.imports)) {
|
||||
rp = shop.resolve_use_path(idx_obj.imports[ri].module_path, ctx)
|
||||
// Fallback: check sibling files in the same directory.
|
||||
if (rp == null) {
|
||||
lp = fd.dirname(fd.realpath(fname)) + '/' + idx_obj.imports[ri].module_path + '.cm'
|
||||
if (fd.is_file(lp)) {
|
||||
rp = lp
|
||||
}
|
||||
}
|
||||
if (rp != null) {
|
||||
idx_obj.imports[ri].resolved_path = rp
|
||||
}
|
||||
ri = ri + 1
|
||||
}
|
||||
}
|
||||
|
||||
var mode = null
|
||||
var span_arg = null
|
||||
var symbol_name = null
|
||||
var file_arg = null
|
||||
var files = []
|
||||
var i = 0
|
||||
var parts = null
|
||||
var filename = null
|
||||
@@ -25,6 +49,7 @@ var line = null
|
||||
var col = null
|
||||
var src = null
|
||||
var idx = null
|
||||
var indexes = []
|
||||
var explain = null
|
||||
var result = null
|
||||
var pipeline = {tokenize: tokenize_mod, parse: parse_mod, fold: fold_mod}
|
||||
@@ -55,12 +80,10 @@ for (i = 0; i < length(args); i++) {
|
||||
log.console("")
|
||||
log.console("Options:")
|
||||
log.console(" --span file:line:col Find symbol at position")
|
||||
log.console(" --symbol name [file] Find symbol by name")
|
||||
log.console(" --symbol name <file>... Find symbol by name across files")
|
||||
$stop()
|
||||
} else if (!starts_with(args[i], '-')) {
|
||||
if (file_arg == null) {
|
||||
file_arg = args[i]
|
||||
}
|
||||
files[] = args[i]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +110,7 @@ if (mode == "span") {
|
||||
|
||||
src = text(fd.slurp(filename))
|
||||
idx = index_mod.index_file(src, filename, pipeline)
|
||||
resolve_imports(idx, filename)
|
||||
explain = explain_mod.make(idx)
|
||||
result = explain.at_span(line, col)
|
||||
|
||||
@@ -99,28 +123,55 @@ if (mode == "span") {
|
||||
}
|
||||
|
||||
if (mode == "symbol") {
|
||||
filename = file_arg
|
||||
|
||||
if (filename == null) {
|
||||
log.error('--symbol requires a file argument')
|
||||
if (length(files) == 0) {
|
||||
log.error('--symbol requires at least one file argument')
|
||||
$stop()
|
||||
}
|
||||
|
||||
if (!fd.is_file(filename)) {
|
||||
log.error('File not found: ' + filename)
|
||||
$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
|
||||
}
|
||||
|
||||
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 (length(files) == 1) {
|
||||
// Single file: use by_symbol for a focused result.
|
||||
filename = files[0]
|
||||
src = text(fd.slurp(filename))
|
||||
idx = index_mod.index_file(src, filename, pipeline)
|
||||
resolve_imports(idx, 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 {
|
||||
print(json.encode(result, true))
|
||||
print("\n")
|
||||
if (result == null || length(result.symbols) == 0) {
|
||||
log.console("Symbol '" + symbol_name + "' not found in " + filename)
|
||||
} else {
|
||||
print(json.encode(result, true))
|
||||
print("\n")
|
||||
}
|
||||
} else if (length(files) > 1) {
|
||||
// Multiple files: index each and search across all.
|
||||
indexes = []
|
||||
i = 0
|
||||
while (i < length(files)) {
|
||||
src = text(fd.slurp(files[i]))
|
||||
idx = index_mod.index_file(src, files[i], pipeline)
|
||||
resolve_imports(idx, 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 {
|
||||
print(json.encode(result, true))
|
||||
print("\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user