feat: allow user to provide custom schema service

This commit is contained in:
Peng Xiao 2018-11-16 10:20:58 +08:00
parent fb04c29c52
commit 5476403375
11 changed files with 37 additions and 89 deletions

View file

@ -1,6 +1,6 @@
{
"name": "monaco-yaml",
"version": "1.2.0",
"version": "1.3.0",
"description": "YAML plugin for the Monaco Editor",
"scripts": {
"compile": "rimraf ./out && yarn compile:umd && yarn compile:esm",

View file

@ -9,7 +9,7 @@ import * as Json from 'jsonc-parser';
import {JSONSchema, JSONSchemaMap} from '../jsonSchema';
import URI from 'vscode-uri';
import * as Strings from '../utils/strings';
import {SchemaRequestService, WorkspaceContextService, PromiseConstructor, Thenable} from '../yamlLanguageService';
import {SchemaRequestService, WorkspaceContextService, Thenable} from '../yamlLanguageService';
import * as nls from 'vscode-nls';
@ -142,7 +142,7 @@ class SchemaHandle implements ISchemaHandle {
this.service = service;
this.url = url;
if (unresolvedSchemaContent) {
this.unresolvedSchema = this.service.promise.resolve(new UnresolvedSchema(unresolvedSchemaContent));
this.unresolvedSchema = Promise.resolve(new UnresolvedSchema(unresolvedSchemaContent));
}
}
@ -242,13 +242,11 @@ export class JSONSchemaService implements IJSONSchemaService {
private contextService: WorkspaceContextService;
private callOnDispose: Function[];
private requestService: SchemaRequestService;
private promiseConstructor: PromiseConstructor;
private customSchemaProvider: CustomSchemaProvider | undefined;
constructor(requestService: SchemaRequestService, contextService?: WorkspaceContextService, promiseConstructor?: PromiseConstructor) {
constructor(requestService: SchemaRequestService, contextService?: WorkspaceContextService) {
this.contextService = contextService;
this.requestService = requestService;
this.promiseConstructor = promiseConstructor || Promise;
this.callOnDispose = [];
this.customSchemaProvider = undefined;
this.contributionSchemas = {};
@ -270,10 +268,6 @@ export class JSONSchemaService implements IJSONSchemaService {
});
}
public get promise() {
return this.promiseConstructor;
}
public dispose(): void {
while (this.callOnDispose.length > 0) {
this.callOnDispose.pop()();
@ -376,13 +370,13 @@ export class JSONSchemaService implements IJSONSchemaService {
if (schemaHandle) {
return schemaHandle.getResolvedSchema();
}
return this.promise.resolve(null);
return Promise.resolve(null);
}
public loadSchema(url: string): Thenable<UnresolvedSchema> {
if (!this.requestService) {
let errorMessage = localize('json.schema.norequestservice', 'Unable to load schema from \'{0}\'. No schema request service available', toDisplayString(url));
return this.promise.resolve(new UnresolvedSchema(<JSONSchema>{}, [errorMessage]));
return Promise.resolve(new UnresolvedSchema(<JSONSchema>{}, [errorMessage]));
}
return this.requestService(url).then(
content => {
@ -507,7 +501,7 @@ export class JSONSchemaService implements IJSONSchemaService {
collectMapEntries(next.definitions, next.properties, next.patternProperties, <JSONSchemaMap>next.dependencies);
collectArrayEntries(next.anyOf, next.allOf, next.oneOf, <JSONSchema[]>next.items, next.schemaSequence);
}
return this.promise.all(openPromises);
return Promise.all(openPromises);
};
return resolveRefs(schema, schema, schemaURL).then(_ => new ResolvedSchema(schema, resolveErrors));
@ -522,7 +516,7 @@ export class JSONSchemaService implements IJSONSchemaService {
return entry.getCombinedSchema(this).getResolvedSchema();
}
}
return this.promise.resolve(null);
return Promise.resolve(null);
};
if (this.customSchemaProvider) {
return this.customSchemaProvider(resource).then(schemaUri => {

View file

@ -11,7 +11,7 @@ import * as Json from 'jsonc-parser';
import * as SchemaService from './jsonSchemaService';
import { JSONSchema } from '../jsonSchema';
import { JSONWorkerContribution, CompletionsCollector } from '../jsonContributions';
import { PromiseConstructor, Thenable } from 'vscode-json-languageservice';
import { Thenable } from 'vscode-json-languageservice';
import { CompletionItem, CompletionItemKind, CompletionList, TextDocument, Position, Range, TextEdit, InsertTextFormat } from 'vscode-languageserver-types';
@ -25,14 +25,12 @@ export class YAMLCompletion {
private schemaService: SchemaService.IJSONSchemaService;
private contributions: JSONWorkerContribution[];
private promise: PromiseConstructor;
private customTags: Array<String>;
private completion: boolean;
constructor(schemaService: SchemaService.IJSONSchemaService, contributions: JSONWorkerContribution[] = [], promiseConstructor?: PromiseConstructor) {
constructor(schemaService: SchemaService.IJSONSchemaService, contributions: JSONWorkerContribution[] = []) {
this.schemaService = schemaService;
this.contributions = contributions;
this.promise = promiseConstructor || Promise;
this.customTags = [];
this.completion = true;
}
@ -53,7 +51,7 @@ export class YAMLCompletion {
}
}
}
return this.promise.resolve(item);
return Promise.resolve(item);
}
public doComplete(document: TextDocument, position: Position, doc): Thenable<CompletionList> {
@ -142,7 +140,6 @@ export class YAMLCompletion {
let collectionPromises: Thenable<any>[] = [];
let addValue = true;
let currentKey = '';
let currentProperty: Parser.PropertyASTNode = null;
if (node) {
@ -152,7 +149,6 @@ export class YAMLCompletion {
if (stringNode.isKey) {
addValue = !(node.parent && ((<Parser.PropertyASTNode>node.parent).value));
currentProperty = node.parent ? <Parser.PropertyASTNode>node.parent : null;
currentKey = document.getText().substring(node.start + 1, node.end - 1);
if (node.parent) {
node = node.parent.parent;
}
@ -209,7 +205,7 @@ export class YAMLCompletion {
this.getCustomTagValueCompletions(collector);
}
return this.promise.all(collectionPromises).then(() => {
return Promise.all(collectionPromises).then(() => {
return result;
});
});

View file

@ -9,7 +9,7 @@
import * as Parser from '../parser/jsonParser';
import * as SchemaService from './jsonSchemaService';
import {JSONWorkerContribution} from '../jsonContributions';
import {PromiseConstructor, Thenable} from 'vscode-json-languageservice';
import {Thenable} from 'vscode-json-languageservice';
import {Hover, TextDocument, Position, Range, MarkedString} from 'vscode-languageserver-types';
import { matchOffsetToDocument } from '../utils/arrUtils';
@ -19,13 +19,11 @@ export class YAMLHover {
private schemaService: SchemaService.IJSONSchemaService;
private contributions: JSONWorkerContribution[];
private promise: PromiseConstructor;
private shouldHover: boolean;
constructor(schemaService: SchemaService.IJSONSchemaService, contributions: JSONWorkerContribution[] = [], promiseConstructor: PromiseConstructor) {
constructor(schemaService: SchemaService.IJSONSchemaService, contributions: JSONWorkerContribution[] = []) {
this.schemaService = schemaService;
this.contributions = contributions;
this.promise = promiseConstructor || Promise;
this.shouldHover = true;
}
@ -38,18 +36,18 @@ export class YAMLHover {
public doHover(document: TextDocument, position: Position, doc): Thenable<Hover> {
if(!this.shouldHover || !document){
return this.promise.resolve(void 0);
return Promise.resolve(void 0);
}
let offset = document.offsetAt(position);
let currentDoc = matchOffsetToDocument(offset, doc);
if(currentDoc === null){
return this.promise.resolve(void 0);
return Promise.resolve(void 0);
}
const currentDocIndex = doc.documents.indexOf(currentDoc);
let node = currentDoc.getNodeFromOffset(offset);
if (!node || (node.type === 'object' || node.type === 'array') && offset > node.start + 1 && offset < node.end - 1) {
return this.promise.resolve(void 0);
return Promise.resolve(void 0);
}
let hoverRangeNode = node;
@ -60,7 +58,7 @@ export class YAMLHover {
let propertyNode = <Parser.PropertyASTNode>node.parent;
node = propertyNode.value;
if (!node) {
return this.promise.resolve(void 0);
return Promise.resolve(void 0);
}
}
}

View file

@ -6,20 +6,16 @@
'use strict';
import { JSONSchemaService, ResolvedSchema } from './jsonSchemaService';
import { JSONDocument, ObjectASTNode, IProblem, ProblemSeverity } from '../parser/jsonParser';
import { TextDocument, Diagnostic, DiagnosticSeverity } from 'vscode-languageserver-types';
import { PromiseConstructor, Thenable, LanguageSettings} from '../yamlLanguageService';
import { DiagnosticSeverity } from 'vscode-languageserver-types';
import { LanguageSettings} from '../yamlLanguageService';
export class YAMLValidation {
private jsonSchemaService: JSONSchemaService;
private promise: PromiseConstructor;
private comments: boolean;
private validationEnabled: boolean;
public constructor(jsonSchemaService, promiseConstructor) {
public constructor(jsonSchemaService) {
this.jsonSchemaService = jsonSchemaService;
this.promise = promiseConstructor;
this.validationEnabled = true;
}
@ -28,11 +24,11 @@ export class YAMLValidation {
this.validationEnabled = shouldValidate.validate;
}
}
public doValidation(textDocument, yamlDocument) {
if(!this.validationEnabled){
return this.promise.resolve([]);
return Promise.resolve([]);
}
return this.jsonSchemaService.getSchemaForResource(textDocument.uri).then(function (schema) {
@ -56,7 +52,7 @@ export class YAMLValidation {
}
if(newSchema && newSchema.errors.length > 0){
for(let curDiagnostic of newSchema.errors){
diagnostics.push({
severity: DiagnosticSeverity.Error,

View file

@ -12,7 +12,7 @@ import { YAMLCompletion } from './services/yamlCompletion';
import { YAMLHover } from './services/yamlHover';
import { YAMLValidation } from './services/yamlValidation';
import { format } from './services/yamlFormatter';
import { JSONDocument } from 'vscode-json-languageservice';
import { JSONDocument, JSONWorkerContribution } from 'vscode-json-languageservice';
import { parse as parseYAML } from "./parser/yamlParser";
export interface LanguageSettings {
@ -26,38 +26,6 @@ export interface LanguageSettings {
export type YAMLDocument = { documents: JSONDocument[] };
export interface PromiseConstructor {
/**
* Creates a new Promise.
* @param executor A callback used to initialize the promise. This callback is passed two arguments:
* a resolve callback used resolve the promise with a value or the result of another promise,
* and a reject callback used to reject the promise with a provided reason or error.
*/
new <T>(executor: (resolve: (value?: T | Thenable<T>) => void, reject: (reason?: any) => void) => void): Thenable<T>;
/**
* Creates a Promise that is resolved with an array of results when all of the provided Promises
* resolve, or rejected when any Promise is rejected.
* @param values An array of Promises.
* @returns A new Promise.
*/
all<T>(values: Array<T | Thenable<T>>): Thenable<T[]>;
/**
* Creates a new rejected promise for the provided reason.
* @param reason The reason the promise was rejected.
* @returns A new rejected Promise.
*/
reject<T>(reason: any): Thenable<T>;
/**
* Creates a new resolved promise for the provided value.
* @param value A promise.
* @returns A promise whose internal state matches the provided promise.
*/
resolve<T>(value: T | Thenable<T>): Thenable<T>;
}
export interface Thenable<R> {
/**
* Attaches callbacks for the resolution and/or rejection of the Promise.
@ -109,15 +77,13 @@ export interface LanguageService {
parseYAMLDocument(document: TextDocument): YAMLDocument;
}
export function getLanguageService(schemaRequestService, workspaceContext, contributions, promiseConstructor?): LanguageService {
let promise = promiseConstructor || Promise;
export function getLanguageService(schemaRequestService: SchemaRequestService, workspaceContext: WorkspaceContextService, contributions: JSONWorkerContribution[]): LanguageService {
let schemaService = new JSONSchemaService(schemaRequestService, workspaceContext);
let completer = new YAMLCompletion(schemaService, contributions, promise);
let hover = new YAMLHover(schemaService, contributions, promise);
let completer = new YAMLCompletion(schemaService, contributions);
let hover = new YAMLHover(schemaService, contributions);
let yamlDocumentSymbols = new YAMLDocumentSymbols();
let yamlValidation = new YAMLValidation(schemaService, promise);
let yamlValidation = new YAMLValidation(schemaService);
return {
configure: (settings) => {

View file

@ -45,7 +45,6 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.yaml.Langua
const diagnosticDefault: monaco.languages.yaml.DiagnosticsOptions = {
validate: true,
schemas: [],
enableSchemaRequest: false,
}
const yamlDefaults = new LanguageServiceDefaultsImpl('yaml', diagnosticDefault);

5
src/monaco.d.ts vendored
View file

@ -29,9 +29,10 @@ declare module monaco.languages.yaml {
}[];
/**
* If set, the schema service would load schema content on-demand with 'fetch' if available
* If not set, the schema service would load schema content on-demand with 'fetch' if available,
* otherwise, it will try to load with the custom schema request.
*/
readonly enableSchemaRequest?: boolean;
readonly schemaRequestService?: (url: string) => Promise<string>;
}
export interface LanguageServiceDefaults {

View file

@ -70,7 +70,7 @@ export class WorkerManager {
createData: {
languageSettings: this._defaults.diagnosticsOptions,
languageId: this._defaults.languageId,
enableSchemaRequest: this._defaults.diagnosticsOptions.enableSchemaRequest
schemaRequestService: this._defaults.diagnosticsOptions.schemaRequestService
}
});

View file

@ -53,9 +53,8 @@ export class YAMLWorker {
this._ctx = ctx;
this._languageSettings = createData.languageSettings;
this._languageId = createData.languageId;
this._languageService = yamlService.getLanguageService(createData.enableSchemaRequest && defaultSchemaRequestService,
null, [], PromiseAdapter,
);
this._languageService = yamlService.getLanguageService(
createData.schemaRequestService || defaultSchemaRequestService, null, []);
this._languageService.configure({ ...this._languageSettings, hover: true, isKubernetes: true });
}
@ -108,7 +107,7 @@ export class YAMLWorker {
export interface ICreateData {
languageId: string;
languageSettings: yamlService.LanguageSettings;
enableSchemaRequest: boolean;
schemaRequestService: (url: string) => Promise<string>;
}
export function create(ctx: IWorkerContext, createData: ICreateData): YAMLWorker {

View file

@ -73,7 +73,6 @@ spec:
});
monaco.languages.yaml.yamlDefaults.setDiagnosticsOptions({
enableSchemaRequest: true,
validate: true,
schemas: [
{