[fix] positions

This commit is contained in:
Andy Bunce 2025-08-19 12:43:04 +01:00
parent 1483a807f4
commit 77bc1e524c
5 changed files with 40 additions and 23 deletions

View file

@ -1 +1 @@
{"cells":[{"kind":2,"language":"xquery","value":"(:<:)\r\n\r\nimport module namespace docs=\"lsp/docs\" at \"/srv/basex/webapp/lsp/docs.xqm\";"},{"kind":2,"language":"xquery","value":"ws:ids()"},{"kind":2,"language":"xquery","value":"let $sock:=foot(ws:ids())\r\nlet $f:=docs:list($sock)\r\nlet $t:=docs:get($sock,$f,\"textDocument\")\r\nreturn map:put($t,\"text\",substring($t?text,1,15))"},{"kind":2,"language":"xquery","value":"let $sock:=foot(ws:ids())\r\nlet $f:=docs:list($sock)\r\nlet $t:=docs:get($sock,$f,\"parse\")\r\nreturn $t/self::ERROR"},{"kind":2,"language":"xquery","value":"let $sock:=foot(ws:ids())\r\nlet $f:=docs:list($sock)\r\nlet $t:=docs:get($sock,$f,\"textDocument\")?text\r\nreturn $t"}]} {"cells":[{"kind":2,"language":"xquery","value":"(:<:)\r\n\r\nimport module namespace docs=\"lsp/docs\" at \"/srv/basex/webapp/lsp/docs.xqm\";"},{"kind":2,"language":"xquery","value":"ws:ids()"},{"kind":2,"language":"xquery","value":"let $sock:=foot(ws:ids())\r\nlet $f:=docs:list($sock)\r\nlet $t:=docs:get($sock,$f,\"textDocument\")\r\nreturn map:put($t,\"text\",substring($t?text,1,15))"},{"kind":2,"language":"xquery","value":"let $sock:=foot(ws:ids())\r\nlet $f:=docs:list($sock)\r\nlet $t:=docs:get($sock,$f,\"parse\")\r\nreturn $t/self::ERROR"},{"kind":2,"language":"xquery","value":"let $sock:=foot(ws:ids())\r\nlet $f:=docs:list($sock)\r\nlet $t:=docs:get($sock,$f,\"textDocument\")\r\nreturn $t"}]}

View file

@ -12,7 +12,7 @@ import module namespace pos="lsp/position" at "../webapp/lsp/position.xqm";
(:~ count lines. :) (:~ count lines. :)
declare %unit:test function test:line-count() { declare %unit:test function test:line-count() {
let $text:=unparsed-text("sample.docs/pdfbox.xqm") let $text:=unparsed-text("sample.docs/pdfbox.xqm")
let $nl:= index-of(string-to-codepoints($text),10)=>trace("SSS ") let $nl:= index-of(string-to-codepoints($text),10)
return unit:assert-equals(count($nl),521) return unit:assert-equals(count($nl),521)
}; };
@ -23,8 +23,21 @@ declare %unit:test function test:resolvePosition() {
return unit:assert-equals($p,18751) return unit:assert-equals($p,18751)
}; };
(:~ convert position. :)
declare %unit:test("expected", "pos:range")
function test:toPosition() {
let $text:="1+2 a"
return pos:toPosition($text,5)
};
(:~ convert position. :)
declare %unit:test
function test:toPosition2() {
let $text:="1+2 a"
return unit:assert-equals(pos:toPosition($text,4),{"line":0,"character":4})
};
(:~ convert all position. :) (:~ convert all position. :)
declare %unit:test function test:toPosition() { declare %unit:test %unit:ignore function test:toPositionAll() {
let $text:=unparsed-text("sample.docs/pdfbox.xqm") let $text:=unparsed-text("sample.docs/pdfbox.xqm")
return for $i in 0 to string-length($text)-1 return for $i in 0 to string-length($text)-1
let $pos:=pos:toPosition($text,$i) let $pos:=pos:toPosition($text,$i)

View file

@ -1,7 +1,5 @@
import module namespace pos="lsp/position" at "../webapp/lsp/position.xqm"; import module namespace pos="lsp/position" at "../webapp/lsp/position.xqm";
let $text:=unparsed-text("sample.docs/pdfbox.xqm") let $text:="1+2 a"
let $nl:= index-of(string-to-codepoints($text),10)
return ( return pos:toPosition($text,5)
pos:toPosition($text,10744),pos:toPosition($text,10745)
)

View file

@ -17,7 +17,7 @@ declare record lsp-diags:nostic(
range as pos:Range, range as pos:Range,
severity as xs:integer, (: enum('error', 'hint', 'info', 'warning') :) severity as xs:integer, (: enum('error', 'hint', 'info', 'warning') :)
message as xs:string, message as xs:string,
code? as xs:string, code as xs:string,
source as xs:string:="xquery" source as xs:string:="xquery"
); );
@ -33,10 +33,11 @@ declare function lsp-diags:publish(
$text as xs:string, $text as xs:string,
$xml as lsp-diags:ParseResult) $xml as lsp-diags:ParseResult)
as map(*){ as map(*){
let $_:=trace($xml,"PABLISH ")
let $diagnostics:=if($xml/self::ERROR) let $diagnostics:=if($xml/self::ERROR)
then array{lsp-diags:parse-error($text, $xml)} then array{lsp-diags:parse-error($text, $xml)}
else array{ lsp-diags:parse-xquery($text,$xml)} else array{ lsp-diags:parse-xquery($text,$xml)}
let $_:=trace($diagnostics,"PIBLISH ")
return {"jsonrpc": "2.0", return {"jsonrpc": "2.0",
"method":"textDocument/publishDiagnostics", "method":"textDocument/publishDiagnostics",
"params":{"uri": $uri, "diagnostics": $diagnostics} "params":{"uri": $uri, "diagnostics": $diagnostics}
@ -44,25 +45,28 @@ as map(*){
}; };
(:~ (:~
<ERROR b="10819" e="10820" o="234" s="43">syntax error, found '}' while expecting [S,'else'] at line 290, column 3: ...} }; ? return bookmark info for children of $outlineItem as s...</ERROR> <ERROR b="10819" e="10820" o="234" s="43">syntax error, found '}' while expecting [S,'else'] at line 290, column 'XPST0003', 'parse error'
assert.equal(markers[0].code, 'XPST0003', 'parse error'); 'XQLT0001', 'previous parse error'
assert.equal(markers[1].code, 'XQLT0001', 'previous parse error');
:) :)
declare function lsp-diags:parse-error($text as xs:string, $xml as element(ERROR)) declare function lsp-diags:parse-error($text as xs:string, $xml as element(ERROR))
as map(*)*{ as map(*)*{
let $dmesg:=$xml/string() let $dmesg:=$xml/string()=>trace("parse-error")
let $dmesg:=translate($dmesg,"&#10;",";") let $dmesg:=translate($dmesg,"&#10;",";")
let $b:=number($xml/@b)-1
let $e:= number($xml/@e)-1
return ( return (
lsp-diags:nostic(pos:Range(pos:toPosition($text, $xml/@b),
pos:toPosition($text, $xml/@e)),
$lsp-diags:severities('error'),
$dmesg,code:="XPST0003"),
lsp-diags:nostic(pos:Range(pos:toPosition($text, $xml/@e +1 ), lsp-diags:nostic(pos:Range(pos:toPosition($text, $b),
pos:toPosition($text, min(($e,string-length($text)-1)))),
1,
$dmesg,'XPST0003'),
if($e ge string-length($text))
then ()
else lsp-diags:nostic(pos:Range(pos:toPosition($text, $e +1 ),
pos:toPosition($text, string-length($text)-1)), pos:toPosition($text, string-length($text)-1)),
$lsp-diags:severities('warning'), 2,
"Unparsed due to previous parser error.", "Unparsed due to previous parser error.",
code:="XQLT0001") "XQLT0001")
) )
}; };

View file

@ -56,7 +56,9 @@ declare function pos:toPosition($text as xs:string,
$index as pos:num $index as pos:num
) )
as pos:Position { as pos:Position {
let $nl:= index-of(string-to-codepoints($text),10) let $nl:= if($index=>trace("IN ") ge string-length($text)=>trace("L "))
then error(xs:QName("pos:range"),"out of range")
else index-of(string-to-codepoints($text),10)
let $line:=pos:lineAt($nl,$index) let $line:=pos:lineAt($nl,$index)
let $off:=if($line eq 0) let $off:=if($line eq 0)
then 0 then 0
@ -70,7 +72,7 @@ return pos:Position($line, $index - $off)
declare function pos:lineAt($nl as xs:integer*,$pos as pos:num) declare function pos:lineAt($nl as xs:integer*,$pos as pos:num)
as xs:integer as xs:integer
{ {
if($pos le head($nl)) if(empty($nl) or $pos le head($nl))
then 0 then 0
else if($pos gt foot($nl)) else if($pos gt foot($nl))
then count($nl) then count($nl)