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"; import module namespace pos="lsp/position" at "../position.xqm"; declare function syms:list($parse as element(),$text as xs:string) 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 }; (: for testing only:) declare function syms:dummy($parse as element(),$text as xs:string ) as lspt:DocumentSymbol*{ let $fr:=(pos:full-range($text),message("dummy")) (: dummy data :) let $nameRange:=$fr return map:for-each($lspt:SymbolKindMap, fn($k,$v){ lspt:DocumentSymbol($k,$v,$fr,$nameRange,`{$k} v:{$v}`) }) }; (:~ just trace :) 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:=syms:localName($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:=syms:localName($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()) }; declare function syms:localName($name as xs:string ) as xs:string{ if(starts-with($name,"Q{")) then substring-after($name,"}") else if(contains($name,":")) then substring-after($name,":") else $name };