[mod] symbols

This commit is contained in:
Andy Bunce 2022-03-06 23:46:59 +00:00
parent 9dd58b2b70
commit e945532956
12 changed files with 272 additions and 203 deletions

View file

@ -4,23 +4,23 @@ const ExtensionTopLevelSection = "basexTools";
export class Configuration {
static get enableXmlTreeView(): boolean {
return this._getForWindow<boolean>("enableXmlTreeView");
return this._getForWindow<boolean>("xmlTree.enableTreeView");
}
static get enableXmlTreeViewMetadata(): boolean {
return this._getForWindow<boolean>("enableXmlTreeViewMetadata");
return this._getForWindow<boolean>("xmlTree.enableViewMetadata");
}
static get enableXmlTreeViewCursorSync(): boolean {
return this._getForWindow<boolean>("enableXmlTreeViewCursorSync");
static get enableViewCursorSync(): boolean {
return this._getForWindow<boolean>("xmlTree.enableViewCursorSync");
}
static get ignoreDefaultNamespace(): boolean {
return this._getForWindow<boolean>("ignoreDefaultNamespace");
return this._getForWindow<boolean>("xpath.ignoreDefaultNamespace");
}
static get persistXPathQuery(): boolean {
return this._getForWindow<boolean>("persistXPathQuery");
return this._getForWindow<boolean>("xpath.persistXPathQuery");
}
static get xmlFormatterImplementation(): string {

View file

@ -1,9 +1,9 @@
// debug messages
import { OutputChannel, window } from "vscode";
// eslint-disable-next-line @typescript-eslint/no-var-requires
const XQLint = require("@quodatum/xqlint").XQLint;
const ver = require("@quodatum/xqlint").version;
const _channel:OutputChannel = window.createOutputChannel("BaseX log");
const _channel:OutputChannel = window.createOutputChannel("BaseX");
function logdate(){
return (new Date()).toISOString().slice(0, 19).replace(/-/g, "/").replace("T", " ");
}
@ -19,5 +19,5 @@ export class channel {
_channel.show
}
}
channel.log("started, XQLint version: "+XQLint.version);
channel.log("started, XQLint version: "+ver);
_channel.show

View file

@ -24,7 +24,9 @@ export class XQueryCompletionItemProvider implements CompletionItemProvider {
case "function":
completionItem.kind = CompletionItemKind.Function;
// eslint-disable-next-line no-case-declarations
const funcStart = (xqLintCompletionItem.value.indexOf(":") + 1);
// eslint-disable-next-line no-case-declarations
const funcEnd = xqLintCompletionItem.value.indexOf("(");
completionItem.insertText = xqLintCompletionItem.value.substring(funcStart, funcEnd);

View file

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-namespace */
export namespace commands {
export const evaluateXPath = "basexTools.evaluateXPath";
export const executeXQuery = "basexTools.executeXQuery";

View file

@ -1,6 +1,6 @@
import {
commands, languages, window, workspace, ExtensionContext, Memento,
TextEditor, TextEditorSelectionChangeEvent, TextEditorSelectionChangeKind, DiagnosticCollection, TextDocument, TextEdit,Range
commands, languages, window, ExtensionContext,
TextEditor, TextEditorSelectionChangeEvent, TextEditorSelectionChangeKind, DiagnosticCollection
} from "vscode";
import { channel } from "./common/logger";
@ -14,7 +14,8 @@ import { evaluateXPath, getCurrentXPath } from "./xpath/commands";
import { executeXQuery } from "./xquery-execution/commands";
import * as constants from "./constants";
import { XQueryFormatter } from "./formatting/XQueryFormatter";
import { XQueryFormatter } from "./formatting/xquery-formatting-provider";
import { Symbols } from './symbols/symbols';
let diagnosticCollectionXQuery: DiagnosticCollection;
@ -32,30 +33,26 @@ export function activate(context: ExtensionContext) {
/* Formatting Features */
const xmlFormattingEditProvider = new XmlFormattingEditProvider(XmlFormatterFactory.getXmlFormatter());
const xqueryFormattingEditProvider = new XQueryFormatter();
context.subscriptions.push(
commands.registerTextEditorCommand(constants.commands.formatAsXml, formatAsXml),
commands.registerTextEditorCommand(constants.commands.xmlToText, xmlToText),
commands.registerTextEditorCommand(constants.commands.textToXml, textToXml),
commands.registerTextEditorCommand(constants.commands.minifyXml, minifyXml),
languages.registerDocumentFormattingEditProvider(xmlXsdDocSelector, xmlFormattingEditProvider),
languages.registerDocumentRangeFormattingEditProvider(xmlXsdDocSelector, xmlFormattingEditProvider)
languages.registerDocumentRangeFormattingEditProvider(xmlXsdDocSelector, xmlFormattingEditProvider),
languages.registerDocumentFormattingEditProvider(xqueryDocSelector, xqueryFormattingEditProvider),
languages.registerDocumentRangeFormattingEditProvider(xqueryDocSelector, xqueryFormattingEditProvider)
);
// 👍 XQuery formatter implemented using API
languages.registerDocumentFormattingEditProvider(constants.languageIds.xquery, {
async provideDocumentFormattingEdits(document: TextDocument): Promise<TextEdit[]> {
try {
const text = XQueryFormatter.format(document.getText())
const entireDocRange = document.validateRange(new Range(0, 0, document.lineCount, 0));
return [TextEdit.replace(entireDocRange, text)];
} catch (e) {
window.showInformationMessage('Format failed -syntax error')
}
}
});
// symbols
const symbols = new Symbols();
context.subscriptions.push(languages.registerDocumentSymbolProvider(constants.languageIds.xquery, symbols));
/* Linting Features */
diagnosticCollectionXQuery = languages.createDiagnosticCollection(constants.diagnosticCollections.xquery);
context.subscriptions.push(
@ -97,7 +94,7 @@ export function activate(context: ExtensionContext) {
export function deactivate() {
// do nothing
};
}
function _handleContextChange(editor: TextEditor): void {
const supportedSchemes = [constants.uriSchemes.file, constants.uriSchemes.untitled];

View file

@ -1,18 +0,0 @@
// format xquery
import { channel } from "../common/logger";
import { XQLint, CodeFormatter } from "@quodatum/xqlint";
export class XQueryFormatter {
static format(xquery: string): string {
channel.log("XQueryFormatter");
const linter = new (XQLint as any)(xquery, { "styleCheck": false });
channel.appendLine("got linter: " + linter.hasSyntaxError());
//if(linter.hasSyntaxError()+linter.hasSyntaxError()) throw new Error("XQuery syntax error")
const ast = linter.getAST()
const formatter = new (CodeFormatter as any)(ast);
const formatted = formatter.format().trim();
channel.log("XQueryFormatter done");
return formatted;
}
}

View file

@ -1,3 +1,4 @@
export * from "./xml-formatter";
export * from "./xml-formatting-edit-provider";
export * from "./xml-formatting-options";
export * from "./xquery-formatting-provider";

View file

@ -1,6 +1,6 @@
import { window, workspace } from "vscode";
import { Configuration, ExtensionState } from "../common";
import { Configuration } from "../common";
import * as constants from "../constants";
import { ClassicXmlFormatter } from "./formatters/classic-xml-formatter";
import { V2XmlFormatter } from "./formatters/v2-xml-formatter";

View file

@ -0,0 +1,33 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
// format xquery
import { XQLint, CodeFormatter } from "@quodatum/xqlint";
import { CancellationToken, DocumentFormattingEditProvider, DocumentRangeFormattingEditProvider,
FormattingOptions, ProviderResult,Range,
TextDocument, TextEdit} from "vscode";
import { channel } from "../common/logger";
function format(xquery: string,document: TextDocument): string {
channel.log("XQueryFormatter" + document.uri);
const linter = new (XQLint as any)(xquery, { "styleCheck": false });
channel.appendLine(" linter hasSyntaxError: " + linter.hasSyntaxError());
//if(linter.hasSyntaxError()+linter.hasSyntaxError()) throw new Error("XQuery syntax error")
const ast = linter.getAST()
const formatter = new (CodeFormatter as any)(ast);
const formatted = formatter.format().trim();
channel.log("XQueryFormatter done");
return formatted;
}
export class XQueryFormatter implements DocumentFormattingEditProvider, DocumentRangeFormattingEditProvider{
provideDocumentFormattingEdits(document: TextDocument, options: FormattingOptions, token: CancellationToken): ProviderResult<TextEdit[]> {
const lastLine = document.lineAt(document.lineCount - 1);
const documentRange = new Range(document.positionAt(0), lastLine.range.end);
return this.provideDocumentRangeFormattingEdits(document, documentRange, options, token);
}
provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, _options: FormattingOptions, _token: CancellationToken): ProviderResult<TextEdit[]> {
const selected = document.getText(range);
const result = format(selected);
return [TextEdit.replace(range, result)];
}
}

45
src/symbols/symbols.ts Normal file
View file

@ -0,0 +1,45 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { XQLint } from '@quodatum/xqlint';
import * as vscode from 'vscode';
import { channel } from "../common/logger";
//
// This class handles Symbols
//
function makeSymbol (name :string,desc :string,icon :vscode.SymbolKind,pos :any) {
const spos = new vscode.Position(pos.sl, pos.sc);
const epos = new vscode.Position(pos.el, pos.ec);
const fullrange=new vscode.Range(spos,epos);
const selrange=new vscode.Range(spos,spos);
return new vscode.DocumentSymbol(name,"var", vscode.SymbolKind.Variable, fullrange, selrange);
}
export class Symbols implements vscode.DocumentSymbolProvider {
provideDocumentSymbols = async (
document: vscode.TextDocument,
token: vscode.CancellationToken
): Promise<vscode.DocumentSymbol[]> => {
channel.log("Symbols: " + document.uri);
const symbols: vscode.DocumentSymbol[] = [];
const text = document.getText();
const linter = new (XQLint as any)(text, { "styleCheck": false });
const xqdoc= linter.getXQDoc();
channel.log(xqdoc.variables);
// type: type,
// pos: pos,
// qname: qname,
// annotations: {}
xqdoc.variables.forEach(v => {
const name = v.name;
const info =makeSymbol(name,"var", vscode.SymbolKind.Variable,v.pos)
symbols.push(info);
});
xqdoc.functions.forEach(v => {
const name = v.name;
const info =makeSymbol(name,"Fu", vscode.SymbolKind.Function,v.pos)
symbols.push(info);
});
channel.log("Symbols done" + document.uri);
return symbols;
};
}