mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-21 12:41:20 -08:00
193 lines
6.5 KiB
Plaintext
193 lines
6.5 KiB
Plaintext
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import * as jsonService from 'vscode-json-languageservice';
|
|
import type { worker } from './fillers/monaco-editor-core';
|
|
import { URI } from 'vscode-uri';
|
|
import { DiagnosticsOptions } from './monaco.contribution';
|
|
|
|
let defaultSchemaRequestService;
|
|
if (typeof fetch !== 'undefined') {
|
|
defaultSchemaRequestService = function (url) {
|
|
return fetch(url).then((response) => response.text());
|
|
};
|
|
}
|
|
|
|
export class JSONWorker {
|
|
private _ctx: worker.IWorkerContext;
|
|
private _languageService: jsonService.LanguageService;
|
|
private _languageSettings: DiagnosticsOptions;
|
|
private _languageId: string;
|
|
|
|
constructor(ctx: worker.IWorkerContext, createData: ICreateData) {
|
|
this._ctx = ctx;
|
|
this._languageSettings = createData.languageSettings;
|
|
this._languageId = createData.languageId;
|
|
this._languageService = jsonService.getLanguageService({
|
|
workspaceContext: {
|
|
resolveRelativePath: (relativePath: string, resource: string) => {
|
|
const base = resource.substr(0, resource.lastIndexOf('/') + 1);
|
|
return resolvePath(base, relativePath);
|
|
}
|
|
},
|
|
schemaRequestService: createData.enableSchemaRequest && defaultSchemaRequestService
|
|
});
|
|
this._languageService.configure(this._languageSettings);
|
|
}
|
|
|
|
async doValidation(uri: string): Promise<jsonService.Diagnostic[]> {
|
|
let document = this._getTextDocument(uri);
|
|
if (document) {
|
|
let jsonDocument = this._languageService.parseJSONDocument(document);
|
|
return this._languageService.doValidation(document, jsonDocument, this._languageSettings);
|
|
}
|
|
return Promise.resolve([]);
|
|
}
|
|
async doComplete(
|
|
uri: string,
|
|
position: jsonService.Position
|
|
): Promise<jsonService.CompletionList> {
|
|
let document = this._getTextDocument(uri);
|
|
let jsonDocument = this._languageService.parseJSONDocument(document);
|
|
return this._languageService.doComplete(document, position, jsonDocument);
|
|
}
|
|
async doResolve(item: jsonService.CompletionItem): Promise<jsonService.CompletionItem> {
|
|
return this._languageService.doResolve(item);
|
|
}
|
|
async doHover(uri: string, position: jsonService.Position): Promise<jsonService.Hover> {
|
|
let document = this._getTextDocument(uri);
|
|
let jsonDocument = this._languageService.parseJSONDocument(document);
|
|
return this._languageService.doHover(document, position, jsonDocument);
|
|
}
|
|
async format(
|
|
uri: string,
|
|
range: jsonService.Range,
|
|
options: jsonService.FormattingOptions
|
|
): Promise<jsonService.TextEdit[]> {
|
|
let document = this._getTextDocument(uri);
|
|
let textEdits = this._languageService.format(document, range, options);
|
|
return Promise.resolve(textEdits);
|
|
}
|
|
async resetSchema(uri: string): Promise<boolean> {
|
|
return Promise.resolve(this._languageService.resetSchema(uri));
|
|
}
|
|
async findDocumentSymbols(uri: string): Promise<jsonService.SymbolInformation[]> {
|
|
let document = this._getTextDocument(uri);
|
|
let jsonDocument = this._languageService.parseJSONDocument(document);
|
|
let symbols = this._languageService.findDocumentSymbols(document, jsonDocument);
|
|
return Promise.resolve(symbols);
|
|
}
|
|
async findDocumentColors(uri: string): Promise<jsonService.ColorInformation[]> {
|
|
let document = this._getTextDocument(uri);
|
|
let jsonDocument = this._languageService.parseJSONDocument(document);
|
|
let colorSymbols = this._languageService.findDocumentColors(document, jsonDocument);
|
|
return Promise.resolve(colorSymbols);
|
|
}
|
|
async getColorPresentations(
|
|
uri: string,
|
|
color: jsonService.Color,
|
|
range: jsonService.Range
|
|
): Promise<jsonService.ColorPresentation[]> {
|
|
let document = this._getTextDocument(uri);
|
|
let jsonDocument = this._languageService.parseJSONDocument(document);
|
|
let colorPresentations = this._languageService.getColorPresentations(
|
|
document,
|
|
jsonDocument,
|
|
color,
|
|
range
|
|
);
|
|
return Promise.resolve(colorPresentations);
|
|
}
|
|
async getFoldingRanges(
|
|
uri: string,
|
|
context?: { rangeLimit?: number }
|
|
): Promise<jsonService.FoldingRange[]> {
|
|
let document = this._getTextDocument(uri);
|
|
let ranges = this._languageService.getFoldingRanges(document, context);
|
|
return Promise.resolve(ranges);
|
|
}
|
|
async getSelectionRanges(
|
|
uri: string,
|
|
positions: jsonService.Position[]
|
|
): Promise<jsonService.SelectionRange[]> {
|
|
let document = this._getTextDocument(uri);
|
|
let jsonDocument = this._languageService.parseJSONDocument(document);
|
|
let ranges = this._languageService.getSelectionRanges(document, positions, jsonDocument);
|
|
return Promise.resolve(ranges);
|
|
}
|
|
private _getTextDocument(uri: string): jsonService.TextDocument {
|
|
let models = this._ctx.getMirrorModels();
|
|
for (let model of models) {
|
|
if (model.uri.toString() === uri) {
|
|
return jsonService.TextDocument.create(
|
|
uri,
|
|
this._languageId,
|
|
model.version,
|
|
model.getValue()
|
|
);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// URI path utilities, will (hopefully) move to vscode-uri
|
|
|
|
const Slash = '/'.charCodeAt(0);
|
|
const Dot = '.'.charCodeAt(0);
|
|
|
|
function isAbsolutePath(path: string) {
|
|
return path.charCodeAt(0) === Slash;
|
|
}
|
|
|
|
function resolvePath(uriString: string, path: string): string {
|
|
if (isAbsolutePath(path)) {
|
|
const uri = URI.parse(uriString);
|
|
const parts = path.split('/');
|
|
return uri.with({ path: normalizePath(parts) }).toString();
|
|
}
|
|
return joinPath(uriString, path);
|
|
}
|
|
|
|
function normalizePath(parts: string[]): string {
|
|
const newParts: string[] = [];
|
|
for (const part of parts) {
|
|
if (part.length === 0 || (part.length === 1 && part.charCodeAt(0) === Dot)) {
|
|
// ignore
|
|
} else if (part.length === 2 && part.charCodeAt(0) === Dot && part.charCodeAt(1) === Dot) {
|
|
newParts.pop();
|
|
} else {
|
|
newParts.push(part);
|
|
}
|
|
}
|
|
if (parts.length > 1 && parts[parts.length - 1].length === 0) {
|
|
newParts.push('');
|
|
}
|
|
let res = newParts.join('/');
|
|
if (parts[0].length === 0) {
|
|
res = '/' + res;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
function joinPath(uriString: string, ...paths: string[]): string {
|
|
const uri = URI.parse(uriString);
|
|
const parts = uri.path.split('/');
|
|
for (let path of paths) {
|
|
parts.push(...path.split('/'));
|
|
}
|
|
return uri.with({ path: normalizePath(parts) }).toString();
|
|
}
|
|
|
|
export interface ICreateData {
|
|
languageId: string;
|
|
languageSettings: DiagnosticsOptions;
|
|
enableSchemaRequest: boolean;
|
|
}
|
|
|
|
export function create(ctx: worker.IWorkerContext, createData: ICreateData): JSONWorker {
|
|
return new JSONWorker(ctx, createData);
|
|
}
|