From 8ba88be05d6b76472e30b986ebb6a4d924bd0848 Mon Sep 17 00:00:00 2001 From: Kevin Decker Date: Sun, 25 Feb 2018 23:26:16 -0600 Subject: [PATCH] Merge yaml language services --- package.json | 5 +- .../documentPositionCalculator.ts | 62 ------ .../services/yamlCompletion.ts | 8 - src/vscode-yaml-languageservice/tsconfig.json | 19 -- .../yamlLanguageService.ts | 187 ------------------ .../services/yamlFormatter.ts | 0 .../services/yamlValidation.ts | 3 +- src/yaml-languageservice/utils/arrUtils.ts | 2 +- .../yamlLanguageService.ts | 54 ++++- 9 files changed, 55 insertions(+), 285 deletions(-) delete mode 100644 src/vscode-yaml-languageservice/documentPositionCalculator.ts delete mode 100644 src/vscode-yaml-languageservice/services/yamlCompletion.ts delete mode 100644 src/vscode-yaml-languageservice/tsconfig.json delete mode 100644 src/vscode-yaml-languageservice/yamlLanguageService.ts rename src/{vscode-yaml-languageservice => yaml-languageservice}/services/yamlFormatter.ts (100%) diff --git a/package.json b/package.json index 174fd83..7b8a9f7 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,7 @@ "scripts": { "compile": "gulp compile", "watch": "gulp watch", - "prepublish": "gulp release", - "install-service-next": "npm install vscode-json-languageservice@next -f -D && npm install vscode-languageserver-types@next -f -D", - "install-service-local": "npm install ../vscode-json-languageservice -f -D && npm install ../vscode-languageserver-node/types -f -D" + "prepublish": "gulp release" }, "author": "Microsoft Corporation", "license": "MIT", @@ -24,6 +22,7 @@ "gulp-requirejs": "^0.1.3", "gulp-tsb": "^2.0.0", "gulp-uglify": "^1.5.3", + "js-yaml": "^3.10.0", "jsonc-parser": "1.0.0", "merge-stream": "^1.0.0", "monaco-editor-core": "^0.10.1", diff --git a/src/vscode-yaml-languageservice/documentPositionCalculator.ts b/src/vscode-yaml-languageservice/documentPositionCalculator.ts deleted file mode 100644 index b408a38..0000000 --- a/src/vscode-yaml-languageservice/documentPositionCalculator.ts +++ /dev/null @@ -1,62 +0,0 @@ -"use strict" - -export function insertionPointReturnValue(pt: number) { - return ((-pt) - 1) -} - -export function binarySearch(array: number[], sought: number) { - - let lower = 0 - let upper = array.length - 1 - - while (lower <= upper) { - let idx = Math.floor((lower + upper) / 2) - const value = array[idx] - - if (value === sought) { - return idx; - } - - if (lower === upper) { - const insertionPoint = (value < sought) ? idx + 1 : idx - return insertionPointReturnValue(insertionPoint) - } - - if (sought > value) { - lower = idx + 1; - } else if (sought < value) { - upper = idx - 1; - } - } -} - -export function getLineStartPositions(text: string) { - const lineStartPositions = [0]; - for (var i = 0; i < text.length; i++) { - const c = text[i]; - - if (c === '\r') { - // Check for Windows encoding, otherwise we are old Mac - if (i + 1 < text.length && text[i + 1] == '\n') { - i++; - } - - lineStartPositions.push(i + 1); - } else if (c === '\n'){ - lineStartPositions.push(i + 1); - } - } - - return lineStartPositions; -} - -export function getPosition(pos: number, lineStartPositions: number[]){ - let line = binarySearch(lineStartPositions, pos) - - if (line < 0){ - const insertionPoint = -1 * line - 1; - line = insertionPoint - 1; - } - - return {line, column: pos - lineStartPositions[line]} -} \ No newline at end of file diff --git a/src/vscode-yaml-languageservice/services/yamlCompletion.ts b/src/vscode-yaml-languageservice/services/yamlCompletion.ts deleted file mode 100644 index e2de544..0000000 --- a/src/vscode-yaml-languageservice/services/yamlCompletion.ts +++ /dev/null @@ -1,8 +0,0 @@ -"use strict" - -import { TextDocument } from "vscode-languageserver-types"; - -export function isInComment(document: TextDocument, start: number, offset: number) { - const text = document.getText().substr(start, offset); - return /(?:^|\s+)#/.test(text); -} \ No newline at end of file diff --git a/src/vscode-yaml-languageservice/tsconfig.json b/src/vscode-yaml-languageservice/tsconfig.json deleted file mode 100644 index 7401570..0000000 --- a/src/vscode-yaml-languageservice/tsconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "compilerOptions": { - "target": "es6", - "module": "umd", - "moduleResolution": "node", - "sourceMap": true, - "declaration": true, - "stripInternal": true, - "outDir": "../lib", - "lib": [ - "es6" - ], - "baseUrl": "../types", - "typeRoots": [ - "../node_modules/@types", - "../types" - ] - } -} \ No newline at end of file diff --git a/src/vscode-yaml-languageservice/yamlLanguageService.ts b/src/vscode-yaml-languageservice/yamlLanguageService.ts deleted file mode 100644 index 8aec1d5..0000000 --- a/src/vscode-yaml-languageservice/yamlLanguageService.ts +++ /dev/null @@ -1,187 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Adam Voss. All rights reserved. - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -import {TextDocument, Position, CompletionItem, CompletionList, Hover, Range, SymbolInformation, Diagnostic, - TextEdit, FormattingOptions, MarkedString} from 'vscode-languageserver-types'; - -import {JSONCompletion} from 'vscode-json-languageservice/lib/services/jsonCompletion'; -import {JSONHover} from 'vscode-json-languageservice/lib/services/jsonHover'; -import {JSONValidation} from 'vscode-json-languageservice/lib/services/jsonValidation'; -import {JSONSchema} from 'vscode-json-languageservice/lib/jsonSchema'; -import {JSONDocumentSymbols} from 'vscode-json-languageservice/lib/services/jsonDocumentSymbols'; -import {parse as JSONDocumentConfig} from 'vscode-json-languageservice/lib/parser/jsonParser'; - -import {parse as parseYAML} from './parser/yamlParser'; -import {isInComment} from './services/yamlCompletion' -import {format as formatYAML} from './services/yamlFormatter'; - -import {schemaContributions} from 'vscode-json-languageservice/lib/services/configuration'; -import {JSONSchemaService} from 'vscode-json-languageservice/lib/services/jsonSchemaService'; -import {JSONWorkerContribution, JSONPath, Segment, CompletionsCollector} from 'vscode-json-languageservice/lib/jsonContributions'; - -export type JSONDocument = {} -export type YAMLDocument = { documents: JSONDocument[]} -export {JSONSchema, JSONWorkerContribution, JSONPath, Segment, CompletionsCollector}; -export {TextDocument, Position, CompletionItem, CompletionList, Hover, Range, SymbolInformation, Diagnostic, - TextEdit, FormattingOptions, MarkedString}; - -export interface LanguageService { - configure(settings: LanguageSettings): void; - doValidation(document: TextDocument, yamlDocument: YAMLDocument): Thenable; - parseYAMLDocument(document: TextDocument): YAMLDocument; - resetSchema(uri: string): boolean; - doResolve(item: CompletionItem): Thenable; - doComplete(document: TextDocument, position: Position, doc: YAMLDocument): Thenable; - findDocumentSymbols(document: TextDocument, doc: YAMLDocument): SymbolInformation[]; - doHover(document: TextDocument, position: Position, doc: YAMLDocument): Thenable; - format(document: TextDocument, options: FormattingOptions): TextEdit[]; -} - -export interface LanguageSettings { - /** - * If set, the validator will return syntax errors. - */ - validate?: boolean; - - /** - * A list of known schemas and/or associations of schemas to file names. - */ - schemas?: SchemaConfiguration[]; -} - -export interface SchemaConfiguration { - /** - * The URI of the schema, which is also the identifier of the schema. - */ - uri: string; - /** - * A list of file names that are associated to the schema. The '*' wildcard can be used. For example '*.schema.json', 'package.json' - */ - fileMatch?: string[]; - /** - * The schema for the given URI. - * If no schema is provided, the schema will be fetched with the schema request service (if available). - */ - schema?: JSONSchema; -} - -export interface WorkspaceContextService { - resolveRelativePath(relativePath: string, resource: string): string; -} -/** - * The schema request service is used to fetch schemas. The result should the schema file comment, or, - * in case of an error, a displayable error string - */ -export interface SchemaRequestService { - (uri: string): Thenable; -} - -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 (executor: (resolve: (value?: T | Thenable) => void, reject: (reason?: any) => void) => void): Thenable; - - /** - * 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(values: Array>): Thenable; - /** - * Creates a new rejected promise for the provided reason. - * @param reason The reason the promise was rejected. - * @returns A new rejected Promise. - */ - reject(reason: any): Thenable; - - /** - * Creates a new resolved promise for the provided value. - * @param value A promise. - * @returns A promise whose internal state matches the provided promise. - */ - resolve(value: T | Thenable): Thenable; - -} - -export interface Thenable { - /** - * Attaches callbacks for the resolution and/or rejection of the Promise. - * @param onfulfilled The callback to execute when the Promise is resolved. - * @param onrejected The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of which ever callback is executed. - */ - then(onfulfilled?: (value: R) => TResult | Thenable, onrejected?: (reason: any) => TResult | Thenable): Thenable; - then(onfulfilled?: (value: R) => TResult | Thenable, onrejected?: (reason: any) => void): Thenable; -} - -export interface LanguageServiceParams { - /** - * The schema request service is used to fetch schemas. The result should the schema file comment, or, - * in case of an error, a displayable error string - */ - schemaRequestService?: SchemaRequestService; - /** - * The workspace context is used to resolve relative paths for relative schema references. - */ - workspaceContext?: WorkspaceContextService; - /** - * An optional set of completion and hover participants. - */ - contributions?: JSONWorkerContribution[]; - /** - * A promise constructor. If not set, the ES5 Promise will be used. - */ - promiseConstructor?: PromiseConstructor; -} - -export function getLanguageService(params: LanguageServiceParams): LanguageService { - let promise = params.promiseConstructor || Promise; - - let jsonSchemaService = new JSONSchemaService(params.schemaRequestService, params.workspaceContext, promise); - jsonSchemaService.setSchemaContributions(schemaContributions); - - let jsonCompletion = new JSONCompletion(jsonSchemaService, params.contributions, promise); - jsonCompletion['isInComment'] = isInComment.bind(jsonCompletion); - - let jsonHover = new JSONHover(jsonSchemaService, params.contributions, promise); - let jsonDocumentSymbols = new JSONDocumentSymbols(jsonSchemaService); - let jsonValidation = new JSONValidation(jsonSchemaService, promise); - - - function doValidation(textDocument: TextDocument, yamlDocument: YAMLDocument) { - var validate: (JSONDocument) => Thenable = - jsonValidation.doValidation.bind(jsonValidation, textDocument) - const validationResults = yamlDocument.documents.map(d => validate(d)) - const resultsPromise = promise.all(validationResults); - return resultsPromise.then(res => ([]).concat(...res)) - } - - return { - configure: (settings: LanguageSettings) => { - jsonSchemaService.clearExternalSchemas(); - if (settings.schemas) { - settings.schemas.forEach(settings => { - jsonSchemaService.registerExternalSchema(settings.uri, settings.fileMatch, settings.schema); - }); - }; - jsonValidation.configure(settings); - }, - resetSchema: (uri: string) => jsonSchemaService.onResourceChange(uri), - doValidation: doValidation, - parseYAMLDocument : (document: TextDocument) => parseYAML(document.getText()), - doResolve: jsonCompletion.doResolve.bind(jsonCompletion), - doComplete: jsonCompletion.doComplete.bind(jsonCompletion), - findDocumentSymbols: jsonDocumentSymbols.findDocumentSymbols.bind(jsonDocumentSymbols), - doHover: jsonHover.doHover.bind(jsonHover), - format: formatYAML - }; -} diff --git a/src/vscode-yaml-languageservice/services/yamlFormatter.ts b/src/yaml-languageservice/services/yamlFormatter.ts similarity index 100% rename from src/vscode-yaml-languageservice/services/yamlFormatter.ts rename to src/yaml-languageservice/services/yamlFormatter.ts diff --git a/src/yaml-languageservice/services/yamlValidation.ts b/src/yaml-languageservice/services/yamlValidation.ts index 2f83c83..6b8a78c 100644 --- a/src/yaml-languageservice/services/yamlValidation.ts +++ b/src/yaml-languageservice/services/yamlValidation.ts @@ -6,8 +6,7 @@ import { JSONSchemaService } from './jsonSchemaService'; import { JSONDocument, ObjectASTNode, IProblem, ProblemSeverity } from '../parser/jsonParser'; import { TextDocument, Diagnostic, DiagnosticSeverity } from 'vscode-languageserver-types'; -import { PromiseConstructor, Thenable } from '../yamlLanguageService'; -import { LanguageSettings } from '../../vscode-yaml-languageservice/yamlLanguageService'; +import { LanguageSettings, PromiseConstructor, Thenable } from '../yamlLanguageService'; export class YAMLValidation { diff --git a/src/yaml-languageservice/utils/arrUtils.ts b/src/yaml-languageservice/utils/arrUtils.ts index 37a900c..b4295f9 100644 --- a/src/yaml-languageservice/utils/arrUtils.ts +++ b/src/yaml-languageservice/utils/arrUtils.ts @@ -1,4 +1,4 @@ -import { YAMLDocument } from "../../vscode-yaml-languageservice/yamlLanguageService"; +import { YAMLDocument } from "../yamlLanguageService"; import { SingleYAMLDocument } from "../parser/yamlParser"; export function removeDuplicates(arr, prop) { diff --git a/src/yaml-languageservice/yamlLanguageService.ts b/src/yaml-languageservice/yamlLanguageService.ts index 73dfbe9..a13127e 100644 --- a/src/yaml-languageservice/yamlLanguageService.ts +++ b/src/yaml-languageservice/yamlLanguageService.ts @@ -1,13 +1,60 @@ + +import { + TextDocument, Position, CompletionItem, CompletionList, Hover, Range, SymbolInformation, Diagnostic, + TextEdit, FormattingOptions, MarkedString +} from 'vscode-languageserver-types'; + import { JSONSchemaService } from './services/jsonSchemaService' -import { TextDocument, Position, CompletionList } from 'vscode-languageserver-types'; import { JSONSchema } from './jsonSchema'; import { parse as parseYAML } from "./parser/yamlParser"; import { YAMLDocumentSymbols } from './services/documentSymbols'; import { YAMLCompletion } from "./services/yamlCompletion"; import { YAMLHover } from "./services/yamlHover"; import { YAMLValidation } from "./services/yamlValidation"; -import { LanguageSettings, YAMLDocument, Diagnostic } from '../vscode-yaml-languageservice/yamlLanguageService'; +import { format as formatYAML } from './services/yamlFormatter'; +export type JSONDocument = {} +export type YAMLDocument = { documents: JSONDocument[] } + +export interface LanguageService { + configure(settings: LanguageSettings): void; + doValidation(document: TextDocument, yamlDocument: YAMLDocument): Thenable; + parseYAMLDocument(document: TextDocument): YAMLDocument; + resetSchema(uri: string): boolean; + doResolve(item: CompletionItem): Thenable; + doComplete(document: TextDocument, position: Position, doc: YAMLDocument): Thenable; + findDocumentSymbols(document: TextDocument, doc: YAMLDocument): SymbolInformation[]; + doHover(document: TextDocument, position: Position, doc: YAMLDocument): Thenable; + format(document: TextDocument, options: FormattingOptions): TextEdit[]; +} + +export interface LanguageSettings { + /** + * If set, the validator will return syntax errors. + */ + validate?: boolean; + + /** + * A list of known schemas and/or associations of schemas to file names. + */ + schemas?: SchemaConfiguration[]; +} + +export interface SchemaConfiguration { + /** + * The URI of the schema, which is also the identifier of the schema. + */ + uri: string; + /** + * A list of file names that are associated to the schema. The '*' wildcard can be used. For example '*.schema.json', 'package.json' + */ + fileMatch?: string[]; + /** + * The schema for the given URI. + * If no schema is provided, the schema will be fetched with the schema request service (if available). + */ + schema?: JSONSchema; +} export interface LanguageSettings { validate?: boolean; //Setting for whether we want to validate the schema schemas?: any[]; //List of schemas @@ -120,6 +167,7 @@ export function getLanguageService(schemaRequestService, workspaceContext, contr doValidation: yamlValidation.doValidation.bind(yamlValidation), doHover: hover.doHover.bind(hover), findDocumentSymbols: yamlDocumentSymbols.findDocumentSymbols.bind(yamlDocumentSymbols), - resetSchema: (uri: string) => schemaService.onResourceChange(uri) + resetSchema: (uri: string) => schemaService.onResourceChange(uri), + format: formatYAML } }