[add] basexTools.xqLintReport

This commit is contained in:
Andy Bunce 2023-02-09 09:51:54 +00:00
parent 2b717e39e6
commit b2f40425e3
13 changed files with 369 additions and 293 deletions

View file

@ -1,25 +1,43 @@
declare module '@quodatum/xqlint'{
import { Position } from "vscode";
export class XQLint{
constructor(source :string, opts? :object);
public getCompletions(pos :object): [object];
public getXQDoc() :XQDoc;
public getXQDoc() :XQDoc;
public getAST(pos? :Position) :any;
public getSctx(pos? :Position) :any;
public getErrors() :[Marker];
public getWarnings() :[Marker];
}
export class Marker{
pos: Position;
type: string;
level: string;
message: string;
}
export interface VarType {
name: string;
pos: any;
}
export interface FunType {
name: string;
params: string[]; // name
pos: boolean;
}
export class XQDoc{
moduleNamespace: string;
description: string;
variables: [VarType];
functions: [FunType];
moduleNamespace: string;
description: string;
variables: [VarDecl];
functions: [FunDecl];
}
export interface VarDecl {
name: string;
type: string;
occurrence?: string;
description: string;
pos: any;
}
export interface FunDecl {
name: string;
arity: number;
params: string[]; // name
description: string;
pos: boolean;
}
export function XQueryLexer() :any;
export function createStaticContext(processor :string) :any;
export function CodeFormatter(ast :object) :any;

View file

@ -8,6 +8,23 @@ const _channel:OutputChannel = window.createOutputChannel("BaseX");
function logdate(){
return (new Date()).toISOString().slice(0, 19).replace(/-/g, "/").replace("T", " ");
}
const replacerFunc = () => {
const visited = new WeakSet();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return (key :any, value :any) => {
if (typeof value === "object" && value !== null) {
if (visited.has(value)) {
return;
}
visited.add(value);
}
return value;
};
};
export function dump(obj :object) {
return JSON.stringify(obj,replacerFunc())
}
export class channel {
static log(msg: string) :void{
@ -16,6 +33,9 @@ export class channel {
static appendLine(msg: string) :void{
_channel.appendLine(msg)
}
static dir(obj: object) :void{
_channel.appendLine(dump(obj))
}
static show() :void{
_channel.show
}

View file

@ -7,7 +7,7 @@ export namespace commands {
export const textToXml = "basexTools.textToXml";
export const getCurrentXPath = "basexTools.getCurrentXPath";
export const minifyXml = "basexTools.minifyXml";
export const getAST = "basexTools.getAST";
export const xqLintReport = "basexTools.xqLintReport";
}
export namespace contextKeys {

View file

@ -8,7 +8,7 @@ import { createDocumentSelector, ExtensionState, Configuration } from "./common"
import { XQueryCompletionItemProvider } from "./completion";
import { XmlFormatterFactory, XmlFormattingEditProvider } from "./formatting";
import { formatAsXml, minifyXml, xmlToText, textToXml } from "./formatting/commands";
import { XQueryLinter,getAst } from "./linting";
import { XQueryLinter,xqLintReport } from "./linting";
import { XmlTreeDataProvider } from "./tree-view";
import { evaluateXPath, getCurrentXPath } from "./xpath/commands";
import { executeXQuery } from "./xquery-execution/commands";
@ -40,7 +40,7 @@ export function activate(context: ExtensionContext) {
commands.registerTextEditorCommand(constants.commands.xmlToText, xmlToText),
commands.registerTextEditorCommand(constants.commands.textToXml, textToXml),
commands.registerTextEditorCommand(constants.commands.minifyXml, minifyXml),
commands.registerTextEditorCommand(constants.commands.getAST, getAst),
commands.registerTextEditorCommand(constants.commands.xqLintReport, xqLintReport),
languages.registerDocumentFormattingEditProvider(xmlXsdDocSelector, xmlFormattingEditProvider),
languages.registerDocumentRangeFormattingEditProvider(xmlXsdDocSelector, xmlFormattingEditProvider),

View file

@ -2,7 +2,7 @@
import { CancellationToken, Hover, HoverProvider, Position, TextDocument } from "vscode";
import { XQLint} from "@quodatum/xqlint";
import { channel } from "../common/logger";
import { channel,dump } from "../common/logger";
export class XQueryHoverProvider implements HoverProvider {
public provideHover(
@ -11,9 +11,19 @@ export class XQueryHoverProvider implements HoverProvider {
token: CancellationToken
): Hover | null {
const linter = new XQLint(document.getText());
const posx=position.translate(1,1); //@TODO
const node=linter.getAST(posx);
const sctx=linter.getCompletions(posx);
channel.log("Hover: " + node.name);
//const dx=dump(node);
//channel.appendLine(dx);
const range = document.getWordRangeAtPosition(position);
const word = document.getText(range);
return new Hover(`XQuery Hover info: ${word} at ${position.line}: ${position.character}`);
// return null; if there is no information to show
return new Hover(`XQuery Hover info: ${word} at ${posx.line}: ${posx.character}
value: ${ node.value }, name: ${ node.name }
`);
return null; //if there is no information to show
}
}

View file

@ -1,23 +0,0 @@
import { Range, TextEditor, Selection } from "vscode";
import { channel } from "../common/logger";
// eslint-disable-next-line @typescript-eslint/no-var-requires
const XQLint = require("@quodatum/xqlint").XQLint;
export function getAst(textEditor: TextEditor): void {
textEditor.edit(textEdit => {
const selections = textEditor.selections;
selections.forEach(selection => {
if (selection.isEmpty) {
selection = new Selection(
textEditor.document.positionAt(0),
textEditor.document.positionAt(textEditor.document.getText().length)
);
}
const text = textEditor.document.getText(new Range(selection.start, selection.end));
const linter = new XQLint(text);
const ast=linter.getAST();
channel.appendLine(ast);
});
});
}

View file

@ -1,2 +1,2 @@
export * from "./xquery-linter";
export * from "./getAST";
export * from "./report";

19
src/linting/report.ts Normal file
View file

@ -0,0 +1,19 @@
import { TextEditor } from "vscode";
import { XQLint} from "@quodatum/xqlint";
import { channel,dump } from "../common/logger";
export function xqLintReport(textEditor: TextEditor): void {
const linter = new XQLint(textEditor.document.getText());
textEditor.edit(textEdit => {
const selections = textEditor.selections;
selections.forEach(selection => {
const pos=selection.start.translate(1,1); //@TODO
const node=linter.getAST(pos);
const sctx=linter.getCompletions(pos);
const dx=dump(node);
channel.appendLine(dx);
});
});
}

View file

@ -1,6 +1,6 @@
import { Diagnostic, DiagnosticSeverity, Position, Range } from "vscode";
import { XQLint} from "@quodatum/xqlint";
const XQLint = require("@quodatum/xqlint").XQLint;
export class XQueryLinter {
static SEVERITY_WARNING = 1;

View file

@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { VarType, FunType, XQLint } from '@quodatum/xqlint';
import { VarDecl, FunDecl, XQLint } from '@quodatum/xqlint';
import {SymbolKind, DocumentSymbol, DocumentSymbolProvider,
Range, Position, TextDocument,CancellationToken} from 'vscode';
import { channel } from "../common/logger";
@ -33,7 +33,7 @@ export class Symbols implements DocumentSymbolProvider {
// pos: pos,
// qname: qname,
// annotations: {}
xqdoc.variables.forEach(function (v: VarType): void {
xqdoc.variables.forEach(function (v: VarDecl): void {
const name = "$" + v.name;
const description="about this variable, some doc here";
channel.log(name + v);
@ -41,7 +41,7 @@ export class Symbols implements DocumentSymbolProvider {
symbols.push(info);
});
xqdoc.functions.forEach(function (f: FunType) {
xqdoc.functions.forEach(function (f: FunDecl) {
const name = f.name + "#" + f.params.length;
const description="about this function, some doc here";
channel.log(name + f);