[mod] ast
This commit is contained in:
parent
e732d190e1
commit
0d80764174
9 changed files with 79 additions and 8 deletions
14
.vscode/launch.json
vendored
Normal file
14
.vscode/launch.json
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
|
||||||
|
{
|
||||||
|
"type": "jdk",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Launch Java App"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
(: parse xq and save result:)
|
(: parse xq and save result:)
|
||||||
import module namespace p="xq4" at "C:\Users\mrwhe\git\quodatum\basex-lsp\webapp\lsp\xq4.xqm";
|
import module namespace p="xq4" at "C:\Users\mrwhe\git\quodatum\basex-lsp\webapp\lsp\ast\xq4.xqm";
|
||||||
declare variable $generator.xpath :="https://raw.githubusercontent.com/dnovatchev/Articles/refs/heads/main/Generators/Code/generator.xq";
|
declare variable $generator.xpath :="https://raw.githubusercontent.com/dnovatchev/Articles/refs/heads/main/Generators/Code/generator.xq";
|
||||||
|
|
||||||
declare variable $pdfbox-good.xqm :="../../test/sample.docs/pdfbox.xqm";
|
declare variable $pdfbox-good.xqm :="../../test/sample.docs/pdfbox.xqm";
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
import module namespace p="xq4" at "C:\Users\mrwhe\git\quodatum\basex-lsp\webapp\lsp\xq4.xqm";
|
import module namespace p="xq4" at "C:\Users\mrwhe\git\quodatum\basex-lsp\webapp\lsp\ast\xq4.xqm";
|
||||||
let $t:=fetch:text("https://raw.githubusercontent.com/dnovatchev/Articles/refs/heads/main/Generators/Code/generator.xq")=>lazy:cache()
|
let $t:=fetch:text("https://raw.githubusercontent.com/dnovatchev/Articles/refs/heads/main/Generators/Code/generator.xq")=>lazy:cache()
|
||||||
return p:parse-Module($t)
|
return p:parse-Module($t)
|
||||||
56
webapp/lsp/ast/ast.xqm
Normal file
56
webapp/lsp/ast/ast.xqm
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
(: Abstract syntax tree
|
||||||
|
@author Andy Bunce
|
||||||
|
:)
|
||||||
|
module namespace ast="lsp/ast";
|
||||||
|
(: import module namespace p="xq4" at "xq4.xqm"; :)
|
||||||
|
import module namespace xq4="java:quodatum.parser.xq4";
|
||||||
|
|
||||||
|
(:~ build :)
|
||||||
|
declare function ast:build($text as xs:string,$uri as xs:string:="")
|
||||||
|
as element(*){
|
||||||
|
let $xml:= xq4:parseModule($text)=>prof:time("⏱️ p:parse-Module " || $uri)
|
||||||
|
return ($xml,
|
||||||
|
message(ast:report($xml),"REP"),
|
||||||
|
message(ast:report(ast:flatten($xml)),"flat")
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
(:~
|
||||||
|
:concrete to abstract: simplify by omitting elements with only one child
|
||||||
|
:)
|
||||||
|
declare function ast:flatten($input as element()) as element() {
|
||||||
|
if (1=count($input/*)) then ast:flatten($input/*)
|
||||||
|
else element {node-name($input) }
|
||||||
|
{$input/@*,
|
||||||
|
for $child in $input/node()
|
||||||
|
return
|
||||||
|
if ($child instance of element())
|
||||||
|
then ast:flatten($child)
|
||||||
|
else $child
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(:-------------------------------------------:)
|
||||||
|
|
||||||
|
declare function ast:report($el as element(*)) {
|
||||||
|
<analysis>
|
||||||
|
<total-elements>{count($el//element())}</total-elements>
|
||||||
|
<max-depth>{ast:max-node-depth($el)}</max-depth>
|
||||||
|
</analysis>
|
||||||
|
};
|
||||||
|
|
||||||
|
declare function ast:max-depth($nodes as node()*) as xs:integer {
|
||||||
|
if (empty($nodes)) then 0
|
||||||
|
else
|
||||||
|
max((
|
||||||
|
for $node in $nodes
|
||||||
|
return
|
||||||
|
if ($node instance of element())
|
||||||
|
then ast:max-depth($node/node()) + 1
|
||||||
|
else ast:max-depth($node/node())
|
||||||
|
))
|
||||||
|
};
|
||||||
|
|
||||||
|
declare function ast:max-node-depth($root as node()) as xs:integer {
|
||||||
|
ast:max-depth($root)
|
||||||
|
};
|
||||||
|
|
@ -4,11 +4,10 @@
|
||||||
@author Andy Bunce
|
@author Andy Bunce
|
||||||
:)
|
:)
|
||||||
module namespace docs="lsp/docs";
|
module namespace docs="lsp/docs";
|
||||||
(: import module namespace p="xq4" at "xq4.xqm"; :)
|
|
||||||
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 'providers/diagnostics.xqm';
|
import module namespace lsp-diags = 'lsp-diags' at 'providers/diagnostics.xqm';
|
||||||
|
import module namespace ast = 'lsp/ast' at 'ast/ast.xqm';
|
||||||
|
|
||||||
(: save $textDocument data as session $socket properties
|
(: save $textDocument data as session $socket properties
|
||||||
@return uri
|
@return uri
|
||||||
|
|
@ -119,7 +118,7 @@ declare function docs:parse(
|
||||||
)as map(*)?
|
)as map(*)?
|
||||||
{
|
{
|
||||||
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:= ast:build($text, $file)
|
||||||
let $diags:=lsp-diags:list($file, $text, $xml)=>prof:time("⏱️ diags " || $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),
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ as hnd:Result{
|
||||||
declare function syms:FunctionDecl($parse as element(FunctionDecl),$state as hnd:Result )
|
declare function syms:FunctionDecl($parse as element(FunctionDecl),$state as hnd:Result )
|
||||||
as hnd:Result{
|
as hnd:Result{
|
||||||
let $name:=syms:localName($parse/UnreservedFunctionEQName)
|
let $name:=syms:localName($parse/UnreservedFunctionEQName)
|
||||||
|
let $prev:=$state?result[$name eq ?name]
|
||||||
let $range:=lspt:Range(lspt:Position(0,0),lspt:Position(0,3))
|
let $range:=lspt:Range(lspt:Position(0,0),lspt:Position(0,3))
|
||||||
let $sym:=lspt:DocumentSymbol($name,$lspt:SymbolKindMap('Method'),$range,$range,"FUN")
|
let $sym:=lspt:DocumentSymbol($name,$lspt:SymbolKindMap('Method'),$range,$range,"FUN")
|
||||||
return ($state?result,$sym)=>hnd:Result(true())
|
return ($state?result,$sym)=>hnd:Result(true())
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@
|
||||||
<link rel="icon" type="image/png" href="../favicon.png" />
|
<link rel="icon" type="image/png" href="../favicon.png" />
|
||||||
|
|
||||||
<!-- Quiet theme + autoloader -->
|
<!-- Quiet theme + autoloader -->
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@quietui/quiet-browser@1.3.0/dist/themes/quiet.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@quietui/quiet-browser@1.4.0/dist/themes/quiet.css">
|
||||||
<script type="module" src="https://cdn.jsdelivr.net/npm/@quietui/quiet-browser@1.3.0/dist/quiet.loader.js"></script>
|
<script type="module" src="https://cdn.jsdelivr.net/npm/@quietui/quiet-browser@1.4.0/dist/quiet.loader.js"></script>
|
||||||
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="grail.css" />
|
<link rel="stylesheet" href="grail.css" />
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,8 @@ $("load").onchange = e => {
|
||||||
});
|
});
|
||||||
$("load").value = "";
|
$("load").value = "";
|
||||||
};
|
};
|
||||||
$("tConnect").addEventListener('quiet-change', event => {
|
$("tConnect").addEventListener('quiet-change', e => {
|
||||||
|
e.preventDefault();
|
||||||
$("popConnect").showPopover()
|
$("popConnect").showPopover()
|
||||||
});
|
});
|
||||||
$("msgIcon").onclick = e => {
|
$("msgIcon").onclick = e => {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue