[mod] clean up tree walk
This commit is contained in:
parent
3465a751bb
commit
e38385b593
8 changed files with 66 additions and 89 deletions
|
@ -1,4 +1,5 @@
|
||||||
import module namespace hnd="lsp/handlers" at "../webapp/lsp/handlers.xqm";
|
import module namespace hnd="lsp/handlers" at "../webapp/lsp/handlers.xqm";
|
||||||
|
import module namespace syms="lsp/symbols" at "../webapp/lsp/providers/documentSymbols.xqm";
|
||||||
declare variable $src:="sample.docs/parse-pdfbox.xml";
|
declare variable $src:="sample.docs/parse-pdfbox.xml";
|
||||||
declare variable $parse:=doc($src)/*;
|
declare variable $parse:=doc($src)/*;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import module namespace hnd="lsp/handlers" at "../webapp/lsp/handlers.xqm";
|
import module namespace syms="lsp/symbols" at "../webapp/lsp/providers/documentSymbols.xqm";
|
||||||
declare variable $src:="sample.docs/parse-pdfbox.xml";
|
declare variable $src:="sample.docs/parse-pdfbox.xml";
|
||||||
declare variable $parse:=doc($src)/*;
|
declare variable $parse:=doc($src)/*;
|
||||||
|
|
||||||
|
|
||||||
hnd:symbols($parse )
|
syms:list($parse )
|
||||||
|
|
|
@ -8,7 +8,7 @@ module namespace docs="lsp/docs";
|
||||||
import module namespace xq4="java:quodatum.parser.xq4";
|
import module namespace xq4="java:quodatum.parser.xq4";
|
||||||
import module namespace pos="lsp/position" at "position.xqm";
|
import module namespace pos="lsp/position" at "position.xqm";
|
||||||
import module namespace rpc = 'rpc' at 'jsonrpc.xqm';
|
import module namespace rpc = 'rpc' at 'jsonrpc.xqm';
|
||||||
import module namespace lsp-diags = 'lsp-diags' at 'lsp-diags.xqm';
|
import module namespace lsp-diags = 'lsp-diags' at 'providers/diagnostics.xqm';
|
||||||
|
|
||||||
(: save $textDocument data as session $socket properties
|
(: save $textDocument data as session $socket properties
|
||||||
@return uri
|
@return uri
|
||||||
|
@ -120,8 +120,12 @@ declare function docs:parse(
|
||||||
{
|
{
|
||||||
let $text:=docs:get($socket,$file,"textDocument")?text
|
let $text:=docs:get($socket,$file,"textDocument")?text
|
||||||
let $xml:= xq4:parseModule($text)=>prof:time("⏱️ p:parse-Module " || $file)
|
let $xml:= xq4:parseModule($text)=>prof:time("⏱️ p:parse-Module " || $file)
|
||||||
|
let $diags:=lsp-diags:list($file, $text, $xml)=>prof:time("⏱️ diags " || $file)
|
||||||
return (
|
return (
|
||||||
ws:set($socket,docs:key($socket,$file,"parse"),$xml),
|
ws:set($socket,docs:key($socket,$file,"parse"),$xml),
|
||||||
lsp-diags:publish($file, $text, $xml)
|
{"jsonrpc": "2.0",
|
||||||
|
"method":"textDocument/publishDiagnostics",
|
||||||
|
"params":{"uri": $file, "diagnostics": array{$diags}}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
};
|
};
|
|
@ -1,14 +0,0 @@
|
||||||
xquery version '4.0';
|
|
||||||
(:~ Symbols from XQuery source file :)
|
|
||||||
module namespace syms="lsp/symbols";
|
|
||||||
|
|
||||||
import module namespace lspt = 'lsp-typedefs' at "lsp-typedefs.xqm";
|
|
||||||
import module namespace pos="lsp/position" at "position.xqm";
|
|
||||||
|
|
||||||
(:~ symbols :)
|
|
||||||
declare function syms:list()
|
|
||||||
as map(*){
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
|
@ -2,37 +2,20 @@
|
||||||
@author Andy Bunce
|
@author Andy Bunce
|
||||||
:)
|
:)
|
||||||
module namespace hnd="lsp/handlers";
|
module namespace hnd="lsp/handlers";
|
||||||
import module namespace lspt = 'lsp-typedefs' at "lsp-typedefs.xqm";
|
|
||||||
|
|
||||||
|
|
||||||
|
(:~ structure returned by tree walkers :)
|
||||||
declare record hnd:Result(
|
declare record hnd:Result(
|
||||||
result as item()*,
|
result as item()*,
|
||||||
skipchildren? as xs:boolean:=false()
|
skipchildren? as xs:boolean:=false()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
declare type hnd:actionFn as fn($parse as element(),$state as hnd:Result ) as hnd:Result;
|
||||||
|
|
||||||
declare function hnd:handle($el as element(*),$state)
|
declare type hnd:actionMap as map(xs:string,hnd:actionFn)
|
||||||
{
|
;
|
||||||
let $f:= function-lookup(xs:QName(name($el)=>trace("SSS")),2)
|
|
||||||
otherwise fn($el,$state){hnd:Result($state,false())}
|
|
||||||
return $f($el,$state)
|
|
||||||
};
|
|
||||||
|
|
||||||
declare function hnd:diags($parse as element(),$diags:=())
|
|
||||||
{
|
|
||||||
let $_:=trace((name($parse),$diags),"diags")
|
|
||||||
let $walk:= hnd:handle($parse,$diags)
|
|
||||||
|
|
||||||
return if($walk?skipchildren)
|
|
||||||
then $walk?result
|
|
||||||
else fold-left($parse/*,$diags,
|
|
||||||
fn($r,$this){
|
|
||||||
hnd:diags($this,$r)
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
declare function hnd:walk($parse as element(),
|
declare function hnd:walk($parse as element(),
|
||||||
$actions as map(*),
|
$actions as hnd:actionMap,
|
||||||
$state as hnd:Result )
|
$state as hnd:Result )
|
||||||
as hnd:Result{
|
as hnd:Result{
|
||||||
|
|
||||||
|
@ -51,37 +34,3 @@ as hnd:Result{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
declare function hnd:symbols($parse as element(),$syms as lspt:DocumentSymbol* :=() )
|
|
||||||
{
|
|
||||||
let $actions:={
|
|
||||||
"ContextValueDecl": hnd:action#2,
|
|
||||||
"VarDecl": hnd:VarDecl#2,
|
|
||||||
"FunctionDecl": hnd:FunctionDecl#2,
|
|
||||||
"ItemTypeDecl": hnd:action#2,
|
|
||||||
"NamedRecordTypeDecl": hnd:action#2
|
|
||||||
}
|
|
||||||
let $state:= hnd:Result(())
|
|
||||||
let $result:= hnd:walk($parse,$actions,$state)
|
|
||||||
return $result?result
|
|
||||||
};
|
|
||||||
|
|
||||||
declare function hnd:action($parse as element(),$state as hnd:Result )
|
|
||||||
as hnd:Result{
|
|
||||||
hnd:Result($state?result,true()) ,message(name($parse),"ACTION: ")
|
|
||||||
};
|
|
||||||
|
|
||||||
declare function hnd:VarDecl($parse as element(VarDecl),$state as hnd:Result )
|
|
||||||
as hnd:Result{
|
|
||||||
let $name:=$parse/VarNameAndType/EQName
|
|
||||||
let $range:=lspt:Range(lspt:Position(0,0),lspt:Position(0,3))
|
|
||||||
let $sym:=lspt:DocumentSymbol($name,$lspt:SymbolKindMap('Variable'),$range,$range,"TODO")
|
|
||||||
return ($state?result,$sym)=>hnd:Result(true())
|
|
||||||
};
|
|
||||||
|
|
||||||
declare function hnd:FunctionDecl($parse as element(FunctionDecl),$state as hnd:Result )
|
|
||||||
as hnd:Result{
|
|
||||||
let $name:=$parse/UnreservedFunctionEQName
|
|
||||||
let $range:=lspt:Range(lspt:Position(0,0),lspt:Position(0,3))
|
|
||||||
let $sym:=lspt:DocumentSymbol($name,$lspt:SymbolKindMap('Method'),$range,$range,"TODO")
|
|
||||||
return ($state?result,$sym)=>hnd:Result(true())
|
|
||||||
};
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ declare variable $lsp-text:methods:=map{
|
||||||
"textDocument/documentSymbol" : lsp-text:symbols#1
|
"textDocument/documentSymbol" : lsp-text:symbols#1
|
||||||
};
|
};
|
||||||
|
|
||||||
declare variable lsp-text:word-reg:="[A-Z]|_|[a-z]|[À-Ö]|[Ø-ö]|[ø-˿]|[Ͱ-ͽ]|[Ϳ-]|[-]|[⁰-]|[Ⰰ-]|[、-]|[豈-﷏]|[ﷰ-<2D>]";
|
declare variable $lsp-text:word-reg:="[A-Z]|_|[a-z]|[À-Ö]|[Ø-ö]|[ø-˿]|[Ͱ-ͽ]|[Ϳ-]|[-]|[⁰-]|[Ⰰ-]|[、-]|[豈-﷏]|[ﷰ-<2D>]";
|
||||||
|
|
||||||
(:~ hover :)
|
(:~ hover :)
|
||||||
declare
|
declare
|
||||||
|
|
|
@ -9,28 +9,21 @@ message: string The message associated with this diagnostic.
|
||||||
renderMessage?: fn(view: EditorView) → Node An optional custom rendering function that displays the message as a DOM node.
|
renderMessage?: fn(view: EditorView) → Node An optional custom rendering function that displays the message as a DOM node.
|
||||||
actions?: readonly Action[] An optional array of actions that can be taken on this diagnostic.
|
actions?: readonly Action[] An optional array of actions that can be taken on this diagnostic.
|
||||||
:)
|
:)
|
||||||
import module namespace lspt = 'lsp-typedefs' at "lsp-typedefs.xqm";
|
import module namespace lspt = 'lsp-typedefs' at "../lsp-typedefs.xqm";
|
||||||
import module namespace pos="lsp/position" at "position.xqm";
|
import module namespace pos="lsp/position" at "../position.xqm";
|
||||||
|
|
||||||
declare type lsp-diags:ParseResult as element(Module|ERROR);
|
declare type lsp-diags:ParseResult as element(Module|ERROR);
|
||||||
|
|
||||||
|
declare function lsp-diags:list(
|
||||||
|
|
||||||
|
|
||||||
declare function lsp-diags:publish(
|
|
||||||
$uri as xs:string,
|
$uri as xs:string,
|
||||||
$text as xs:string,
|
$text as xs:string,
|
||||||
$xml as lsp-diags:ParseResult)
|
$xml as lsp-diags:ParseResult)
|
||||||
as map(*){
|
as map(*)*{
|
||||||
|
|
||||||
let $diagnostics:=if($xml/self::ERROR)
|
if($xml/self::ERROR)
|
||||||
then array{lsp-diags:parse-error($text, $xml)}
|
then lsp-diags:parse-error($text, $xml)
|
||||||
else array{ lsp-diags:parse-xquery($text,$xml)}
|
else lsp-diags:parse-xquery($text,$xml)
|
||||||
|
|
||||||
return {"jsonrpc": "2.0",
|
|
||||||
"method":"textDocument/publishDiagnostics",
|
|
||||||
"params":{"uri": $uri, "diagnostics": $diagnostics}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
(:~
|
(:~
|
44
webapp/lsp/providers/documentSymbols.xqm
Normal file
44
webapp/lsp/providers/documentSymbols.xqm
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
xquery version '4.0';
|
||||||
|
(:~ Symbols from walking the parse tree :)
|
||||||
|
module namespace syms="lsp/symbols";
|
||||||
|
import module namespace hnd="lsp/handlers" at "../handlers.xqm";
|
||||||
|
import module namespace lspt = 'lsp-typedefs' at "../lsp-typedefs.xqm";
|
||||||
|
|
||||||
|
declare function syms:list($parse as element(),$syms as lspt:DocumentSymbol* :=() )
|
||||||
|
{
|
||||||
|
let $actions as hnd:actionMap :={
|
||||||
|
"ContextValueDecl": syms:action#2,
|
||||||
|
"VarDecl": syms:VarDecl#2,
|
||||||
|
"FunctionDecl": syms:FunctionDecl#2,
|
||||||
|
"ItemTypeDecl": syms:action#2,
|
||||||
|
"NamedRecordTypeDecl": syms:action#2
|
||||||
|
}
|
||||||
|
let $state:= hnd:Result(())
|
||||||
|
let $result:= hnd:walk($parse,$actions,$state)
|
||||||
|
return $result?result
|
||||||
|
};
|
||||||
|
|
||||||
|
declare function syms:action($parse as element(),$state as hnd:Result )
|
||||||
|
as hnd:Result{
|
||||||
|
hnd:Result($state?result,true()) ,message(name($parse),"ACTION: ")
|
||||||
|
};
|
||||||
|
|
||||||
|
declare function syms:VarDecl($parse as element(VarDecl),$state as hnd:Result )
|
||||||
|
as hnd:Result{
|
||||||
|
let $name:=$parse/VarNameAndType/EQName
|
||||||
|
let $length:=string($parse)=>string-length()
|
||||||
|
let $range:=lspt:Range(lspt:Position(0,0),lspt:Position(0,3))
|
||||||
|
let $sym:=lspt:DocumentSymbol($name,$lspt:SymbolKindMap('Variable'),$range,$range,"TODO")
|
||||||
|
return ($state?result,$sym)=>hnd:Result(true())
|
||||||
|
};
|
||||||
|
|
||||||
|
declare function syms:FunctionDecl($parse as element(FunctionDecl),$state as hnd:Result )
|
||||||
|
as hnd:Result{
|
||||||
|
let $name:=$parse/UnreservedFunctionEQName
|
||||||
|
let $range:=lspt:Range(lspt:Position(0,0),lspt:Position(0,3))
|
||||||
|
let $sym:=lspt:DocumentSymbol($name,$lspt:SymbolKindMap('Method'),$range,$range,"TODO")
|
||||||
|
return ($state?result,$sym)=>hnd:Result(true())
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue