lsp explain and index
This commit is contained in:
@@ -13,9 +13,11 @@ var symbols = use('symbols')
|
||||
// These are the same functions the compiler uses internally.
|
||||
var tokenize_mod = use('tokenize')
|
||||
var parse_mod = use('parse')
|
||||
var index_mod = use('index')
|
||||
var explain_mod = use('explain')
|
||||
|
||||
// Create analysis module bound to tokenize/parse
|
||||
var analysis = analysis_make(tokenize_mod, parse_mod)
|
||||
// Create analysis module bound to tokenize/parse/index
|
||||
var analysis = analysis_make(tokenize_mod, parse_mod, index_mod)
|
||||
|
||||
// Document store: URI -> {text, version, ast, tokens, errors}
|
||||
var docs = {}
|
||||
@@ -54,7 +56,9 @@ var handle_initialize = function(id, params) {
|
||||
},
|
||||
hoverProvider: true,
|
||||
definitionProvider: true,
|
||||
documentSymbolProvider: true
|
||||
documentSymbolProvider: true,
|
||||
referencesProvider: true,
|
||||
renameProvider: {prepareProvider: true}
|
||||
},
|
||||
serverInfo: {
|
||||
name: "pit-lsp",
|
||||
@@ -144,6 +148,159 @@ var handle_document_symbol = function(id, params) {
|
||||
protocol.respond(id, result)
|
||||
}
|
||||
|
||||
// Handle textDocument/references request.
|
||||
var handle_references = function(id, params) {
|
||||
var uri = params.textDocument.uri
|
||||
var pos = params.position
|
||||
var doc = docs[uri]
|
||||
var result = []
|
||||
var tok = null
|
||||
var name = null
|
||||
var refs = null
|
||||
var _i = 0
|
||||
var ref = null
|
||||
var expl = null
|
||||
var sym_result = null
|
||||
if (doc != null && doc.index != null) {
|
||||
tok = analysis.token_at(doc, pos.line, pos.character)
|
||||
if (tok != null && tok.kind == "name" && tok.value != null) {
|
||||
name = tok.value
|
||||
refs = doc.index.reverse_refs[name]
|
||||
if (refs != null) {
|
||||
_i = 0
|
||||
while (_i < length(refs)) {
|
||||
ref = refs[_i]
|
||||
if (ref.span != null) {
|
||||
result[] = {
|
||||
uri: uri,
|
||||
range: {
|
||||
start: {line: ref.span.from_row, character: ref.span.from_col},
|
||||
end: {line: ref.span.to_row, character: ref.span.to_col}
|
||||
}
|
||||
}
|
||||
}
|
||||
_i = _i + 1
|
||||
}
|
||||
}
|
||||
// Also include the declaration itself if found
|
||||
expl = explain_mod.make(doc.index)
|
||||
sym_result = expl.by_symbol(name)
|
||||
if (sym_result != null && length(sym_result.symbols) > 0) {
|
||||
_i = 0
|
||||
while (_i < length(sym_result.symbols)) {
|
||||
if (sym_result.symbols[_i].decl_span != null) {
|
||||
result[] = {
|
||||
uri: uri,
|
||||
range: {
|
||||
start: {line: sym_result.symbols[_i].decl_span.from_row, character: sym_result.symbols[_i].decl_span.from_col},
|
||||
end: {line: sym_result.symbols[_i].decl_span.to_row, character: sym_result.symbols[_i].decl_span.to_col}
|
||||
}
|
||||
}
|
||||
}
|
||||
_i = _i + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
protocol.respond(id, result)
|
||||
}
|
||||
|
||||
// Handle textDocument/prepareRename request.
|
||||
var handle_prepare_rename = function(id, params) {
|
||||
var uri = params.textDocument.uri
|
||||
var pos = params.position
|
||||
var doc = docs[uri]
|
||||
var tok = null
|
||||
var name = null
|
||||
var result = null
|
||||
var expl = null
|
||||
var sym_result = null
|
||||
if (doc != null) {
|
||||
tok = analysis.token_at(doc, pos.line, pos.character)
|
||||
if (tok != null && tok.kind == "name" && tok.value != null) {
|
||||
name = tok.value
|
||||
// Don't allow renaming intrinsics
|
||||
if (doc.index != null) {
|
||||
expl = explain_mod.make(doc.index)
|
||||
sym_result = expl.by_symbol(name)
|
||||
if (sym_result != null && length(sym_result.symbols) > 0) {
|
||||
result = {
|
||||
range: {
|
||||
start: {line: tok.from_row, character: tok.from_column},
|
||||
end: {line: tok.to_row, character: tok.to_column}
|
||||
},
|
||||
placeholder: name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
protocol.respond(id, result)
|
||||
}
|
||||
|
||||
// Handle textDocument/rename request.
|
||||
var handle_rename = function(id, params) {
|
||||
var uri = params.textDocument.uri
|
||||
var pos = params.position
|
||||
var new_name = params.newName
|
||||
var doc = docs[uri]
|
||||
var tok = null
|
||||
var name = null
|
||||
var edits = []
|
||||
var refs = null
|
||||
var _i = 0
|
||||
var ref = null
|
||||
var expl = null
|
||||
var sym_result = null
|
||||
if (doc != null && doc.index != null) {
|
||||
tok = analysis.token_at(doc, pos.line, pos.character)
|
||||
if (tok != null && tok.kind == "name" && tok.value != null) {
|
||||
name = tok.value
|
||||
expl = explain_mod.make(doc.index)
|
||||
sym_result = expl.by_symbol(name)
|
||||
// Add edit for declaration
|
||||
if (sym_result != null && length(sym_result.symbols) > 0) {
|
||||
_i = 0
|
||||
while (_i < length(sym_result.symbols)) {
|
||||
if (sym_result.symbols[_i].decl_span != null) {
|
||||
edits[] = {
|
||||
range: {
|
||||
start: {line: sym_result.symbols[_i].decl_span.from_row, character: sym_result.symbols[_i].decl_span.from_col},
|
||||
end: {line: sym_result.symbols[_i].decl_span.to_row, character: sym_result.symbols[_i].decl_span.to_col}
|
||||
},
|
||||
newText: new_name
|
||||
}
|
||||
}
|
||||
_i = _i + 1
|
||||
}
|
||||
}
|
||||
// Add edits for all references
|
||||
refs = doc.index.reverse_refs[name]
|
||||
if (refs != null) {
|
||||
_i = 0
|
||||
while (_i < length(refs)) {
|
||||
ref = refs[_i]
|
||||
if (ref.span != null) {
|
||||
edits[] = {
|
||||
range: {
|
||||
start: {line: ref.span.from_row, character: ref.span.from_col},
|
||||
end: {line: ref.span.to_row, character: ref.span.to_col}
|
||||
},
|
||||
newText: new_name
|
||||
}
|
||||
}
|
||||
_i = _i + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var changes = {}
|
||||
if (length(edits) > 0) {
|
||||
changes[uri] = edits
|
||||
}
|
||||
protocol.respond(id, {changes: changes})
|
||||
}
|
||||
|
||||
// Dispatch a single message. Wrapped in a function for disruption handling.
|
||||
var dispatch_message = function(msg) {
|
||||
var method = msg.method
|
||||
@@ -167,6 +324,12 @@ var dispatch_message = function(msg) {
|
||||
handle_definition(msg.id, msg.params)
|
||||
} else if (method == "textDocument/documentSymbol") {
|
||||
handle_document_symbol(msg.id, msg.params)
|
||||
} else if (method == "textDocument/references") {
|
||||
handle_references(msg.id, msg.params)
|
||||
} else if (method == "textDocument/prepareRename") {
|
||||
handle_prepare_rename(msg.id, msg.params)
|
||||
} else if (method == "textDocument/rename") {
|
||||
handle_rename(msg.id, msg.params)
|
||||
} else if (method == "shutdown") {
|
||||
protocol.respond(msg.id, null)
|
||||
return "shutdown"
|
||||
|
||||
Reference in New Issue
Block a user