(: tools to analyse xml parse tree @author Andy Bunce :) module namespace hnd="lsp/handlers"; import module namespace lspt = 'lsp-typedefs' at "lsp-typedefs.xqm"; declare record hnd:Result( result as item()*, skipchildren? as xs:boolean:=false() ); declare function hnd:handle($el as element(*),$state) { 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(), $actions as map(*), $state as hnd:Result ) as hnd:Result{ let $action:=$actions(name($parse)) let $result:= if(exists($action)) then $action($parse,$state) else hnd:Result($state) return if($result?skipchildren) then $result else fold-left( $parse/*,$state, fn($state,$this){hnd:walk($this, $actions, $state)} ) }; 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()) };