[mod] symbol ranges
This commit is contained in:
parent
2d0ae19026
commit
fc56a3d505
5 changed files with 52 additions and 39 deletions
|
|
@ -5,7 +5,7 @@ module namespace hnd="lsp/handlers";
|
||||||
|
|
||||||
|
|
||||||
(:~ structure returned by tree walkers :)
|
(:~ structure returned by tree walkers :)
|
||||||
declare record hnd:Result(
|
declare record hnd:State(
|
||||||
result as item()*,
|
result as item()*,
|
||||||
skipchildren? as xs:boolean:=false(),
|
skipchildren? as xs:boolean:=false(),
|
||||||
extras?
|
extras?
|
||||||
|
|
@ -13,23 +13,23 @@ declare record hnd:Result(
|
||||||
|
|
||||||
declare type hnd:actionFn as fn(
|
declare type hnd:actionFn as fn(
|
||||||
$parse as element(),
|
$parse as element(),
|
||||||
$state as hnd:Result
|
$state as hnd:State
|
||||||
) as hnd:Result;
|
) as hnd:State;
|
||||||
|
|
||||||
declare type hnd:actionMap as map(xs:string,hnd:actionFn);
|
declare type hnd:actionMap as map(xs:string,hnd:actionFn);
|
||||||
|
|
||||||
declare function hnd:walk($parse as element(),
|
declare function hnd:walk($parse as element(),
|
||||||
$actions as hnd:actionMap,
|
$actions as hnd:actionMap,
|
||||||
$state as hnd:Result )
|
$state as hnd:State )
|
||||||
as hnd:Result
|
as hnd:State
|
||||||
{
|
{
|
||||||
let $action:=$actions(name($parse))
|
let $action:=$actions(name($parse))
|
||||||
let $result:= if(exists($action))
|
let $state:= if(exists($action))
|
||||||
then $action($parse,$state)
|
then $action($parse,$state)
|
||||||
else hnd:Result($state)
|
else $state
|
||||||
|
|
||||||
return if($result?skipchildren)
|
return if($state?skipchildren)
|
||||||
then $result
|
then $state
|
||||||
else fold-left(
|
else fold-left(
|
||||||
$parse/*,$state,
|
$parse/*,$state,
|
||||||
fn($state,$this){hnd:walk($this, $actions, $state)}
|
fn($state,$this){hnd:walk($this, $actions, $state)}
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ function lsp-ws:message(
|
||||||
$message as xs:string
|
$message as xs:string
|
||||||
) as empty-sequence() {
|
) as empty-sequence() {
|
||||||
|
|
||||||
let $json := rpc:parse($message=>trace("IN: "))
|
let $json := rpc:parse($message)
|
||||||
return if(exists($json))
|
return if(exists($json))
|
||||||
then rpc:reply($json)
|
then rpc:reply($json)
|
||||||
else message($message,"bad RPC: ")
|
else message($message,"bad RPC: ")
|
||||||
|
|
|
||||||
|
|
@ -66,13 +66,13 @@ as lspt:Diagnostic*
|
||||||
(: test data :)
|
(: test data :)
|
||||||
declare function lsp-diags:parse-xquery($text as xs:string, $parse as element(Module))
|
declare function lsp-diags:parse-xquery($text as xs:string, $parse as element(Module))
|
||||||
as map(*)*{
|
as map(*)*{
|
||||||
let $state:= hnd:Result(())
|
let $state:= hnd:State(())
|
||||||
let $result:= hnd:walk($parse,$lsp-diags:actions,$state)
|
let $result:= hnd:walk($parse,$lsp-diags:actions,$state)
|
||||||
return $result?result
|
return $result?result
|
||||||
};
|
};
|
||||||
|
|
||||||
declare function lsp-diags:Module($parse as element(Module),$state as hnd:Result )
|
declare function lsp-diags:Module($parse as element(Module),$state as hnd:State )
|
||||||
as hnd:Result{
|
as hnd:State{
|
||||||
let $new:=if(exists($parse/VersionDecl)=>trace("has ver: "))
|
let $new:=if(exists($parse/VersionDecl)=>trace("has ver: "))
|
||||||
then ()
|
then ()
|
||||||
else let $text:="dddjjjjjjjjjjjjjjjj"
|
else let $text:="dddjjjjjjjjjjjjjjjj"
|
||||||
|
|
@ -86,7 +86,10 @@ as hnd:Result{
|
||||||
"No XQuery version declaration present",
|
"No XQuery version declaration present",
|
||||||
"XQLT???")
|
"XQLT???")
|
||||||
return (
|
return (
|
||||||
hnd:Result(($state?result,$new=>trace(" VER ")),true())
|
$state
|
||||||
|
=>map:put("result",($state?result,$new=>trace(" VER ")))
|
||||||
|
=>map:put("skipchildren",true())
|
||||||
|
|
||||||
,message(name($parse),"Module: ")
|
,message(name($parse),"Module: ")
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
@ -15,9 +15,9 @@ declare variable $syms:actions as hnd:actionMap :={
|
||||||
|
|
||||||
declare function syms:list($parse as element(),$text as xs:string)
|
declare function syms:list($parse as element(),$text as xs:string)
|
||||||
as lspt:DocumentSymbol*{
|
as lspt:DocumentSymbol*{
|
||||||
let $state:= hnd:Result(())
|
let $state:= hnd:State((),false(),{"text":$text})
|
||||||
let $result:= hnd:walk($parse,$syms:actions,$state)
|
let $state:= hnd:walk($parse,$syms:actions,$state)
|
||||||
return $result?result
|
return $state?result
|
||||||
};
|
};
|
||||||
|
|
||||||
(: for testing only:)
|
(: for testing only:)
|
||||||
|
|
@ -33,37 +33,46 @@ as lspt:DocumentSymbol*{
|
||||||
};
|
};
|
||||||
|
|
||||||
(:~ just trace :)
|
(:~ just trace :)
|
||||||
declare function syms:action($parse as element(),$state as hnd:Result )
|
declare function syms:action($parse as element(),$state as hnd:State )
|
||||||
as hnd:Result{
|
as hnd:State{
|
||||||
hnd:Result($state?result,true()) ,message(name($parse),"ACTION: ")
|
$state ,message(name($parse),"ACTION: ")
|
||||||
};
|
};
|
||||||
|
|
||||||
declare function syms:VarDecl($parse as element(VarDecl),$state as hnd:Result )
|
declare function syms:VarDecl($parse as element(VarDecl),$state as hnd:State )
|
||||||
as hnd:Result{
|
as hnd:State{
|
||||||
let $name:=syms:localName($parse/VarNameAndType/EQName)
|
let $name:=syms:localName($parse/VarNameAndType/EQName)
|
||||||
let $length:=string($parse)=>string-length()
|
let $length:=string($parse)=>string-length()
|
||||||
let $range:=lspt:Range(lspt:Position(0,0),lspt:Position(0,3))
|
let $range:=pos:range-from-ast($parse,$state?extras?text)=>trace("POSSSS")
|
||||||
let $sym:=lspt:DocumentSymbol($name,$lspt:SymbolKindMap('Variable'),$range,$range,"VAR")
|
let $full-range:=$range
|
||||||
return ($state?result,$sym)=>hnd:Result(true())
|
let $sym:=lspt:DocumentSymbol($name,$lspt:SymbolKindMap('Variable'),$range,$full-range,"VAR")
|
||||||
|
return $state
|
||||||
|
=>map:put("result",($state?result,$sym))
|
||||||
|
=>map:put("skipchildren",true())
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
declare function syms:FunctionDecl($parse as element(FunctionDecl),$state as hnd:Result )
|
declare function syms:FunctionDecl($parse as element(FunctionDecl),$state as hnd:State )
|
||||||
as hnd:Result{
|
as hnd:State{
|
||||||
let $name:=syms:localName($parse/UnreservedFunctionEQName)
|
let $name:=syms:localName($parse/UnreservedFunctionEQName)
|
||||||
let $prev:=$state?result[$name eq ?name]
|
let $prev:=$state?result[$name eq ?name]
|
||||||
let $range:=pos:range-from-ast($parse,$state?context?text)=>trace("POSSSS")
|
let $range:=pos:range-from-ast($parse,$state?extras?text)=>trace("POSSSS")
|
||||||
let $full-range:=$range
|
let $full-range:=$range
|
||||||
let $sym:=lspt:DocumentSymbol($name,$lspt:SymbolKindMap('Method'),$range,$full-range,"FUN")
|
let $sym:=lspt:DocumentSymbol($name,$lspt:SymbolKindMap('Method'),$range,$full-range,"FUN")
|
||||||
return ($state?result,$sym)=>hnd:Result(true())
|
return $state
|
||||||
|
=>map:put("result",($state?result,$sym))
|
||||||
|
=>map:put("skipchildren",true())
|
||||||
};
|
};
|
||||||
|
|
||||||
declare function syms:NamedRecordTypeDecl($parse as element(NamedRecordTypeDecl), $state as hnd:Result )
|
declare function syms:NamedRecordTypeDecl($parse as element(NamedRecordTypeDecl), $state as hnd:State )
|
||||||
as hnd:Result{
|
as hnd:State{
|
||||||
let $name:=syms:localName($parse/EQName)
|
let $name:=syms:localName($parse/EQName)
|
||||||
let $range:=lspt:Range(lspt:Position(0,0),lspt:Position(0,3))
|
let $range:=pos:range-from-ast($parse,$state?extras?text)=>trace("POSSSS")
|
||||||
let $sym:=lspt:DocumentSymbol($name,$lspt:SymbolKindMap('TypeParameter'),$range,$range,"--RECORD")
|
let $full-range:=$range
|
||||||
|
let $sym:=lspt:DocumentSymbol($name,$lspt:SymbolKindMap('TypeParameter'),$range,$full-range,"--RECORD")
|
||||||
=>trace("RECORD")
|
=>trace("RECORD")
|
||||||
return ($state?result,$sym)=>hnd:Result(true())
|
return $state
|
||||||
|
=>map:put("result",($state?result,$sym))
|
||||||
|
=>map:put("skipchildren",true())
|
||||||
};
|
};
|
||||||
|
|
||||||
declare function syms:localName($name as xs:string )
|
declare function syms:localName($name as xs:string )
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ const view = new lsp.EditorView({
|
||||||
parent: document.getElementById("editor")
|
parent: document.getElementById("editor")
|
||||||
});
|
});
|
||||||
let doc = "xquery version '3.1';\n(:~ comment:)\nmodule namespace pdfbox='ns';\n";
|
let doc = "xquery version '3.1';\n(:~ comment:)\nmodule namespace pdfbox='ns';\n";
|
||||||
var client;
|
var client; // https://codemirror.net/docs/ref/#lsp-client
|
||||||
var extLint;
|
var extLsp; // https://codemirror.net/docs/ref/#lsp-client.LSPPlugin
|
||||||
var workspace = {
|
var workspace = {
|
||||||
"file:///some/file.xqm": null
|
"file:///some/file.xqm": null
|
||||||
};
|
};
|
||||||
|
|
@ -74,8 +74,9 @@ $("cmdList").onclick = e => {
|
||||||
$("symList").addEventListener("itemSelected", e => {
|
$("symList").addEventListener("itemSelected", e => {
|
||||||
const sel = e.detail.selectionRange;
|
const sel = e.detail.selectionRange;
|
||||||
console.log("SYM selection range", sel);
|
console.log("SYM selection range", sel);
|
||||||
const an = 17 * e.detail.kind
|
const an = extLsp.fromPosition(sel.start)
|
||||||
view.dispatch({ selection: { anchor: an, head: an + 34 }, scrollIntoView: true });
|
const hd = extLsp.fromPosition(sel.end)
|
||||||
|
view.dispatch({ selection: { anchor: an, head: hd}, scrollIntoView: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
$("lint").onclick = async e => {
|
$("lint").onclick = async e => {
|
||||||
|
|
@ -158,7 +159,7 @@ function connect() {
|
||||||
client.connect(transport);
|
client.connect(transport);
|
||||||
$("popConnect").hidePopover();
|
$("popConnect").hidePopover();
|
||||||
$("tConnect").checked=true;
|
$("tConnect").checked=true;
|
||||||
let extLsp = client.plugin(file, "xquery");
|
extLsp = client.plugin(file, "xquery");
|
||||||
|
|
||||||
view.dispatch({
|
view.dispatch({
|
||||||
effects: lsp.StateEffect.appendConfig.of(
|
effects: lsp.StateEffect.appendConfig.of(
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue