Complete residential site build with Docker Compose & Gitea Actions deployment
This commit is contained in:
+23
@@ -0,0 +1,23 @@
|
||||
import { SingleYAMLDocument } from '../parser/yamlParser07';
|
||||
import { JSONDocument } from '../parser/jsonDocument';
|
||||
import { ResolvedSchema } from 'vscode-json-languageservice/lib/umd/services/jsonSchemaService';
|
||||
/**
|
||||
* Retrieve schema by auto-detecting the Kubernetes GroupVersionKind (GVK) from the document.
|
||||
* If there is no definition for the GVK in the main kubernetes schema,
|
||||
* the schema is then retrieved from the CRD catalog.
|
||||
* Public for testing purpose, not part of the API.
|
||||
* @param doc
|
||||
* @param crdCatalogURI The URL of the CRD catalog to retrieve the schema from
|
||||
* @param kubernetesSchema The main kubernetes schema, if it includes a definition for the GVK it will be used
|
||||
*/
|
||||
export declare function autoDetectKubernetesSchemaFromDocument(doc: SingleYAMLDocument | JSONDocument, crdCatalogURI: string, kubernetesSchema: ResolvedSchema): string | undefined;
|
||||
/**
|
||||
* Retrieve the group, version and kind from the document.
|
||||
* Public for testing purpose, not part of the API.
|
||||
* @param doc
|
||||
*/
|
||||
export declare function getGroupVersionKindFromDocument(doc: SingleYAMLDocument | JSONDocument): {
|
||||
group: string;
|
||||
version: string;
|
||||
kind: string;
|
||||
} | undefined;
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
import { SingleYAMLDocument } from '../parser/yamlParser07';
|
||||
/**
|
||||
* Retrieve schema by auto-detecting the Kubernetes GroupVersionKind (GVK) from the document.
|
||||
* If there is no definition for the GVK in the main kubernetes schema,
|
||||
* the schema is then retrieved from the CRD catalog.
|
||||
* Public for testing purpose, not part of the API.
|
||||
* @param doc
|
||||
* @param crdCatalogURI The URL of the CRD catalog to retrieve the schema from
|
||||
* @param kubernetesSchema The main kubernetes schema, if it includes a definition for the GVK it will be used
|
||||
*/
|
||||
export function autoDetectKubernetesSchemaFromDocument(doc, crdCatalogURI, kubernetesSchema) {
|
||||
const res = getGroupVersionKindFromDocument(doc);
|
||||
if (!res) {
|
||||
return undefined;
|
||||
}
|
||||
const { group, version, kind } = res;
|
||||
if (!group || !version || !kind) {
|
||||
return undefined;
|
||||
}
|
||||
const k8sSchema = kubernetesSchema.schema;
|
||||
const kubernetesBuildIns = (k8sSchema.oneOf || [])
|
||||
.map((s) => {
|
||||
if (typeof s === 'boolean') {
|
||||
return undefined;
|
||||
}
|
||||
return s._$ref || s.$ref;
|
||||
})
|
||||
.filter((ref) => ref)
|
||||
.map((ref) => ref.replace('_definitions.json#/definitions/', '').toLowerCase());
|
||||
const groupWithoutK8sIO = group.replace('.k8s.io', '');
|
||||
const k8sTypeName = `io.k8s.api.${groupWithoutK8sIO.toLowerCase()}.${version.toLowerCase()}.${kind.toLowerCase()}`;
|
||||
if (kubernetesBuildIns.includes(k8sTypeName)) {
|
||||
return undefined;
|
||||
}
|
||||
if (k8sTypeName.includes('openshift.io')) {
|
||||
return `${crdCatalogURI}/openshift/v4.15-strict/${kind.toLowerCase()}_${group.toLowerCase()}_${version.toLowerCase()}.json`;
|
||||
}
|
||||
const schemaURL = `${crdCatalogURI}/${group.toLowerCase()}/${kind.toLowerCase()}_${version.toLowerCase()}.json`;
|
||||
return schemaURL;
|
||||
}
|
||||
/**
|
||||
* Retrieve the group, version and kind from the document.
|
||||
* Public for testing purpose, not part of the API.
|
||||
* @param doc
|
||||
*/
|
||||
export function getGroupVersionKindFromDocument(doc) {
|
||||
if (doc instanceof SingleYAMLDocument) {
|
||||
try {
|
||||
const rootJSON = doc.root.internalNode.toJSON();
|
||||
if (!rootJSON) {
|
||||
return undefined;
|
||||
}
|
||||
const groupVersion = rootJSON['apiVersion'];
|
||||
if (!groupVersion) {
|
||||
return undefined;
|
||||
}
|
||||
const [group, version] = groupVersion.split('/');
|
||||
if (!group || !version) {
|
||||
return undefined;
|
||||
}
|
||||
const kind = rootJSON['kind'];
|
||||
if (!kind) {
|
||||
return undefined;
|
||||
}
|
||||
return { group, version, kind };
|
||||
}
|
||||
catch (error) {
|
||||
console.error('Error parsing YAML document:', error);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
//# sourceMappingURL=crdUtil.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"crdUtil.js","sourceRoot":"","sources":["../../../../src/languageservice/services/crdUtil.ts"],"names":[],"mappings":"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"}
|
||||
Generated
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
import { SymbolInformation, DocumentSymbol } from 'vscode-languageserver-types';
|
||||
import { YAMLSchemaService } from './yamlSchemaService';
|
||||
import { DocumentSymbolsContext } from 'vscode-json-languageservice/lib/umd/jsonLanguageTypes';
|
||||
import { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
import { Telemetry } from '../telemetry';
|
||||
export declare class YAMLDocumentSymbols {
|
||||
private readonly telemetry?;
|
||||
private jsonDocumentSymbols;
|
||||
constructor(schemaService: YAMLSchemaService, telemetry?: Telemetry);
|
||||
findDocumentSymbols(document: TextDocument, context?: DocumentSymbolsContext): SymbolInformation[];
|
||||
findHierarchicalDocumentSymbols(document: TextDocument, context?: DocumentSymbolsContext): DocumentSymbol[];
|
||||
}
|
||||
Generated
Vendored
+67
@@ -0,0 +1,67 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Red Hat, Inc. 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.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { JSONDocumentSymbols } from 'vscode-json-languageservice/lib/umd/services/jsonDocumentSymbols';
|
||||
import { yamlDocumentsCache } from '../parser/yaml-documents';
|
||||
import { isMap, isSeq } from 'yaml';
|
||||
export class YAMLDocumentSymbols {
|
||||
constructor(schemaService, telemetry) {
|
||||
this.telemetry = telemetry;
|
||||
this.jsonDocumentSymbols = new JSONDocumentSymbols(schemaService);
|
||||
// override 'getKeyLabel' to handle complex mapping
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
this.jsonDocumentSymbols.getKeyLabel = (property) => {
|
||||
const keyNode = property.keyNode.internalNode;
|
||||
let name = '';
|
||||
if (isMap(keyNode)) {
|
||||
name = '{}';
|
||||
}
|
||||
else if (isSeq(keyNode)) {
|
||||
name = '[]';
|
||||
}
|
||||
else {
|
||||
name = keyNode.source;
|
||||
}
|
||||
return name;
|
||||
};
|
||||
}
|
||||
findDocumentSymbols(document, context = { resultLimit: Number.MAX_VALUE }) {
|
||||
let results = [];
|
||||
try {
|
||||
const doc = yamlDocumentsCache.getYamlDocument(document);
|
||||
if (!doc || doc['documents'].length === 0) {
|
||||
return null;
|
||||
}
|
||||
for (const yamlDoc of doc['documents']) {
|
||||
if (yamlDoc.root) {
|
||||
results = results.concat(this.jsonDocumentSymbols.findDocumentSymbols(document, yamlDoc, context));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
this.telemetry?.sendError('yaml.documentSymbols.error', err);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
findHierarchicalDocumentSymbols(document, context = { resultLimit: Number.MAX_VALUE }) {
|
||||
let results = [];
|
||||
try {
|
||||
const doc = yamlDocumentsCache.getYamlDocument(document);
|
||||
if (!doc || doc['documents'].length === 0) {
|
||||
return null;
|
||||
}
|
||||
for (const yamlDoc of doc['documents']) {
|
||||
if (yamlDoc.root) {
|
||||
results = results.concat(this.jsonDocumentSymbols.findDocumentSymbols2(document, yamlDoc, context));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
this.telemetry?.sendError('yaml.hierarchicalDocumentSymbols.error', err);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=documentSymbols.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"documentSymbols.js","sourceRoot":"","sources":["../../../../src/languageservice/services/documentSymbols.ts"],"names":[],"mappings":"AAAA;;;;gGAIgG;AAIhG,OAAO,EAAE,mBAAmB,EAAE,MAAM,kEAAkE,CAAC;AAGvG,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAQ,MAAM,MAAM,CAAC;AAE1C,MAAM,OAAO,mBAAmB;IAG9B,YACE,aAAgC,EACf,SAAqB;QAArB,cAAS,GAAT,SAAS,CAAY;QAEtC,IAAI,CAAC,mBAAmB,GAAG,IAAI,mBAAmB,CAAC,aAAa,CAAC,CAAC;QAElE,mDAAmD;QACnD,8DAA8D;QAC9D,IAAI,CAAC,mBAAmB,CAAC,WAAW,GAAG,CAAC,QAAa,EAAE,EAAE;YACvD,MAAM,OAAO,GAAS,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC;YACpD,IAAI,IAAI,GAAG,EAAE,CAAC;YACd,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE;gBAClB,IAAI,GAAG,IAAI,CAAC;aACb;iBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE;gBACzB,IAAI,GAAG,IAAI,CAAC;aACb;iBAAM;gBACL,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;aACvB;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;IACJ,CAAC;IAEM,mBAAmB,CACxB,QAAsB,EACtB,UAAkC,EAAE,WAAW,EAAE,MAAM,CAAC,SAAS,EAAE;QAEnE,IAAI,OAAO,GAAG,EAAE,CAAC;QACjB,IAAI;YACF,MAAM,GAAG,GAAG,kBAAkB,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YACzD,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE;gBACzC,OAAO,IAAI,CAAC;aACb;YAED,KAAK,MAAM,OAAO,IAAI,GAAG,CAAC,WAAW,CAAC,EAAE;gBACtC,IAAI,OAAO,CAAC,IAAI,EAAE;oBAChB,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;iBACpG;aACF;SACF;QAAC,OAAO,GAAG,EAAE;YACZ,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,4BAA4B,EAAE,GAAG,CAAC,CAAC;SAC9D;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAEM,+BAA+B,CACpC,QAAsB,EACtB,UAAkC,EAAE,WAAW,EAAE,MAAM,CAAC,SAAS,EAAE;QAEnE,IAAI,OAAO,GAAG,EAAE,CAAC;QACjB,IAAI;YACF,MAAM,GAAG,GAAG,kBAAkB,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YACzD,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE;gBACzC,OAAO,IAAI,CAAC;aACb;YAED,KAAK,MAAM,OAAO,IAAI,GAAG,CAAC,WAAW,CAAC,EAAE;gBACtC,IAAI,OAAO,CAAC,IAAI,EAAE;oBAChB,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,oBAAoB,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;iBACrG;aACF;SACF;QAAC,OAAO,GAAG,EAAE;YACZ,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,wCAAwC,EAAE,GAAG,CAAC,CAAC;SAC1E;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
|
||||
Generated
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
import { SingleYAMLDocument } from '../parser/yamlParser07';
|
||||
import { JSONDocument } from '../parser/jsonDocument';
|
||||
/**
|
||||
* Retrieve schema if declared as modeline.
|
||||
* Public for testing purpose, not part of the API.
|
||||
* @param doc
|
||||
*/
|
||||
export declare function getSchemaFromModeline(doc: SingleYAMLDocument | JSONDocument): string;
|
||||
export declare function isModeline(lineText: string): boolean;
|
||||
Generated
Vendored
+32
@@ -0,0 +1,32 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Red Hat, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { SingleYAMLDocument } from '../parser/yamlParser07';
|
||||
/**
|
||||
* Retrieve schema if declared as modeline.
|
||||
* Public for testing purpose, not part of the API.
|
||||
* @param doc
|
||||
*/
|
||||
export function getSchemaFromModeline(doc) {
|
||||
if (doc instanceof SingleYAMLDocument) {
|
||||
const yamlLanguageServerModeline = doc.lineComments.find((lineComment) => {
|
||||
return isModeline(lineComment);
|
||||
});
|
||||
if (yamlLanguageServerModeline != undefined) {
|
||||
const schemaMatchs = yamlLanguageServerModeline.match(/\$schema=\S+/g);
|
||||
if (schemaMatchs !== null && schemaMatchs.length >= 1) {
|
||||
if (schemaMatchs.length >= 2) {
|
||||
console.log('Several $schema attributes have been found on the yaml-language-server modeline. The first one will be picked.');
|
||||
}
|
||||
return schemaMatchs[0].substring('$schema='.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
export function isModeline(lineText) {
|
||||
const matchModeline = lineText.match(/^#\s+yaml-language-server\s*:/g);
|
||||
return matchModeline !== null && matchModeline.length === 1;
|
||||
}
|
||||
//# sourceMappingURL=modelineUtil.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"modelineUtil.js","sourceRoot":"","sources":["../../../../src/languageservice/services/modelineUtil.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAG5D;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAsC;IAC1E,IAAI,GAAG,YAAY,kBAAkB,EAAE;QACrC,MAAM,0BAA0B,GAAG,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE;YACvE,OAAO,UAAU,CAAC,WAAW,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QACH,IAAI,0BAA0B,IAAI,SAAS,EAAE;YAC3C,MAAM,YAAY,GAAG,0BAA0B,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;YACvE,IAAI,YAAY,KAAK,IAAI,IAAI,YAAY,CAAC,MAAM,IAAI,CAAC,EAAE;gBACrD,IAAI,YAAY,CAAC,MAAM,IAAI,CAAC,EAAE;oBAC5B,OAAO,CAAC,GAAG,CACT,gHAAgH,CACjH,CAAC;iBACH;gBACD,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;aACrD;SACF;KACF;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACvE,OAAO,aAAa,KAAK,IAAI,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,CAAC;AAC9D,CAAC"}
|
||||
Generated
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
import { Connection, WorkspaceFolder } from 'vscode-languageserver';
|
||||
import { URI } from 'vscode-uri';
|
||||
import { WorkspaceContextService } from '../yamlLanguageService';
|
||||
export interface FileSystem {
|
||||
readFile(fsPath: string, encoding?: string): Promise<string>;
|
||||
}
|
||||
/**
|
||||
* Handles schema content requests given the schema URI
|
||||
* @param uri can be a local file, vscode request, http(s) request or a custom request
|
||||
*/
|
||||
export declare const schemaRequestHandler: (connection: Connection, uri: string, workspaceFolders: WorkspaceFolder[], workspaceRoot: URI, useVSCodeContentRequest: boolean, fs: FileSystem, isWeb: boolean) => Promise<string>;
|
||||
export declare const workspaceContext: WorkspaceContextService;
|
||||
Generated
Vendored
+84
@@ -0,0 +1,84 @@
|
||||
import { join } from 'path';
|
||||
import { getErrorStatusDescription, xhr } from 'request-light';
|
||||
import * as URL from 'url';
|
||||
import { RequestType } from 'vscode-languageserver';
|
||||
import { URI } from 'vscode-uri';
|
||||
import { CustomSchemaContentRequest, VSCodeContentRequest } from '../../requestTypes';
|
||||
import { isRelativePath, relativeToAbsolutePath } from '../utils/paths';
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
var FSReadUri;
|
||||
(function (FSReadUri) {
|
||||
FSReadUri.type = new RequestType('fs/readUri');
|
||||
})(FSReadUri || (FSReadUri = {}));
|
||||
/**
|
||||
* Handles schema content requests given the schema URI
|
||||
* @param uri can be a local file, vscode request, http(s) request or a custom request
|
||||
*/
|
||||
export const schemaRequestHandler = async (connection, uri, workspaceFolders, workspaceRoot, useVSCodeContentRequest, fs, isWeb) => {
|
||||
if (!uri) {
|
||||
return Promise.reject('No schema specified');
|
||||
}
|
||||
// If the requested schema URI is a relative file path
|
||||
// Convert it into a proper absolute path URI
|
||||
if (isRelativePath(uri)) {
|
||||
// HACK: the fs/readUri extension is only available with vscode-yaml,
|
||||
// and this fix is specific to vscode-yaml on web, so don't use it in other cases
|
||||
if (workspaceFolders.length === 1 && isWeb) {
|
||||
const wsUri = URI.parse(workspaceFolders[0].uri);
|
||||
const wsDirname = wsUri.path;
|
||||
const modifiedUri = wsUri.with({ path: join(wsDirname, uri) });
|
||||
try {
|
||||
return connection.sendRequest(FSReadUri.type, modifiedUri.toString());
|
||||
}
|
||||
catch (e) {
|
||||
connection.window.showErrorMessage(`failed to get content of '${modifiedUri}': ${e}`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
uri = relativeToAbsolutePath(workspaceFolders, workspaceRoot, uri);
|
||||
}
|
||||
}
|
||||
let scheme = URI.parse(uri).scheme.toLowerCase();
|
||||
// test if uri is windows path, ie starts with 'c:\'
|
||||
if (/^[a-z]:[\\/]/i.test(uri)) {
|
||||
const winUri = URI.file(uri);
|
||||
scheme = winUri.scheme.toLowerCase();
|
||||
uri = winUri.toString();
|
||||
}
|
||||
// If the requested schema is a local file, read and return the file contents
|
||||
if (scheme === 'file') {
|
||||
const fsPath = URI.parse(uri).fsPath;
|
||||
return fs.readFile(fsPath, 'UTF-8').catch(() => {
|
||||
// If there was an error reading the file, return empty error message
|
||||
// Otherwise return the file contents as a string
|
||||
return '';
|
||||
});
|
||||
}
|
||||
// HTTP(S) requests are sent and the response result is either the schema content or an error
|
||||
if (scheme === 'http' || scheme === 'https') {
|
||||
// If we are running inside of VSCode we need to make a content request. This content request
|
||||
// will make it so that schemas behind VPN's will resolve correctly
|
||||
if (useVSCodeContentRequest) {
|
||||
return connection.sendRequest(VSCodeContentRequest.type, uri).then((responseText) => {
|
||||
return responseText;
|
||||
}, (error) => {
|
||||
return Promise.reject(error.message);
|
||||
});
|
||||
}
|
||||
// Send the HTTP(S) schema content request and return the result
|
||||
const headers = { 'Accept-Encoding': 'gzip, deflate' };
|
||||
return xhr({ url: uri, followRedirects: 5, headers }).then((response) => {
|
||||
return response.responseText;
|
||||
}, (error) => {
|
||||
return Promise.reject(error.responseText || getErrorStatusDescription(error.status) || error.toString());
|
||||
});
|
||||
}
|
||||
// Neither local file nor vscode, nor HTTP(S) schema request, so send it off as a custom request
|
||||
return connection.sendRequest(CustomSchemaContentRequest.type, uri);
|
||||
};
|
||||
export const workspaceContext = {
|
||||
resolveRelativePath: (relativePath, resource) => {
|
||||
return URL.resolve(resource, relativePath);
|
||||
},
|
||||
};
|
||||
//# sourceMappingURL=schemaRequestHandler.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"schemaRequestHandler.js","sourceRoot":"","sources":["../../../../src/languageservice/services/schemaRequestHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,yBAAyB,EAAE,GAAG,EAAe,MAAM,eAAe,CAAC;AAC5E,OAAO,KAAK,GAAG,MAAM,KAAK,CAAC;AAC3B,OAAO,EAAc,WAAW,EAAmB,MAAM,uBAAuB,CAAC;AACjF,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACtF,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAOxE,2DAA2D;AAC3D,IAAU,SAAS,CAElB;AAFD,WAAU,SAAS;IACJ,cAAI,GAAyC,IAAI,WAAW,CAAC,YAAY,CAAC,CAAC;AAC1F,CAAC,EAFS,SAAS,KAAT,SAAS,QAElB;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EACvC,UAAsB,EACtB,GAAW,EACX,gBAAmC,EACnC,aAAkB,EAClB,uBAAgC,EAChC,EAAc,EACd,KAAc,EACG,EAAE;IACnB,IAAI,CAAC,GAAG,EAAE;QACR,OAAO,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;KAC9C;IAED,sDAAsD;IACtD,6CAA6C;IAC7C,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE;QACvB,qEAAqE;QACrE,iFAAiF;QACjF,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,EAAE;YAC1C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACjD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC;YAC7B,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YAC/D,IAAI;gBACF,OAAO,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,EAAE,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC;aACvE;YAAC,OAAO,CAAC,EAAE;gBACV,UAAU,CAAC,MAAM,CAAC,gBAAgB,CAAC,6BAA6B,WAAW,MAAM,CAAC,EAAE,CAAC,CAAC;aACvF;SACF;aAAM;YACL,GAAG,GAAG,sBAAsB,CAAC,gBAAgB,EAAE,aAAa,EAAE,GAAG,CAAC,CAAC;SACpE;KACF;IAED,IAAI,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;IAEjD,oDAAoD;IACpD,IAAI,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QAC7B,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QACrC,GAAG,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;KACzB;IAED,6EAA6E;IAC7E,IAAI,MAAM,KAAK,MAAM,EAAE;QACrB,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;QAErC,OAAO,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YAC7C,qEAAqE;YACrE,iDAAiD;YACjD,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;KACJ;IAED,6FAA6F;IAC7F,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,OAAO,EAAE;QAC3C,6FAA6F;QAC7F,mEAAmE;QACnE,IAAI,uBAAuB,EAAE;YAC3B,OAAO,UAAU,CAAC,WAAW,CAAC,oBAAoB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,CAChE,CAAC,YAAY,EAAE,EAAE;gBACf,OAAO,YAAY,CAAC;YACtB,CAAC,EACD,CAAC,KAAK,EAAE,EAAE;gBACR,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACvC,CAAC,CACiB,CAAC;SACtB;QAED,gEAAgE;QAChE,MAAM,OAAO,GAAG,EAAE,iBAAiB,EAAE,eAAe,EAAE,CAAC;QACvD,OAAO,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,eAAe,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,CACxD,CAAC,QAAQ,EAAE,EAAE;YACX,OAAO,QAAQ,CAAC,YAAY,CAAC;QAC/B,CAAC,EACD,CAAC,KAAkB,EAAE,EAAE;YACrB,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,IAAI,yBAAyB,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC3G,CAAC,CACF,CAAC;KACH;IAED,gGAAgG;IAChG,OAAO,UAAU,CAAC,WAAW,CAAC,0BAA0B,CAAC,IAAI,EAAE,GAAG,CAAoB,CAAC;AACzF,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAA4B;IACvD,mBAAmB,EAAE,CAAC,YAAoB,EAAE,QAAgB,EAAE,EAAE;QAC9D,OAAO,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAC7C,CAAC;CACF,CAAC"}
|
||||
Generated
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
import { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
import { Diagnostic } from 'vscode-languageserver-types';
|
||||
import { SingleYAMLDocument } from '../../parser/yaml-documents';
|
||||
import { AdditionalValidator } from './types';
|
||||
export declare class MapKeyOrderValidator implements AdditionalValidator {
|
||||
validate(document: TextDocument, yamlDoc: SingleYAMLDocument): Diagnostic[];
|
||||
}
|
||||
Generated
Vendored
+35
@@ -0,0 +1,35 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Red Hat. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { Diagnostic, DiagnosticSeverity, Range } from 'vscode-languageserver-types';
|
||||
import { isMap, visit } from 'yaml';
|
||||
export class MapKeyOrderValidator {
|
||||
validate(document, yamlDoc) {
|
||||
const result = [];
|
||||
visit(yamlDoc.internalDocument, (key, node) => {
|
||||
if (isMap(node)) {
|
||||
for (let i = 1; i < node.items.length; i++) {
|
||||
if (compare(node.items[i - 1], node.items[i]) > 0) {
|
||||
const range = createRange(document, node.items[i - 1]);
|
||||
result.push(Diagnostic.create(range, `Wrong ordering of key "${node.items[i - 1].key}" in mapping`, DiagnosticSeverity.Error, 'mapKeyOrder'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
function createRange(document, node) {
|
||||
const keySourceToken = node.key.srcToken;
|
||||
const start = keySourceToken.offset;
|
||||
const end = start + keySourceToken.source.length;
|
||||
return Range.create(document.positionAt(start), document.positionAt(end));
|
||||
}
|
||||
function compare(thiz, that) {
|
||||
const thatKey = String(that.key);
|
||||
const thisKey = String(thiz.key);
|
||||
return thisKey.localeCompare(thatKey);
|
||||
}
|
||||
//# sourceMappingURL=map-key-order.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"map-key-order.js","sourceRoot":"","sources":["../../../../../src/languageservice/services/validation/map-key-order.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAGhG,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AACpF,OAAO,EAAE,KAAK,EAAc,KAAK,EAAE,MAAM,MAAM,CAAC;AAKhD,MAAM,OAAO,oBAAoB;IAC/B,QAAQ,CAAC,QAAsB,EAAE,OAA2B;QAC1D,MAAM,MAAM,GAAG,EAAE,CAAC;QAElB,KAAK,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;YAC5C,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE;gBACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;oBAC1C,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;wBACjD,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;wBACvD,MAAM,CAAC,IAAI,CACT,UAAU,CAAC,MAAM,CACf,KAAK,EACL,0BAA0B,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,cAAc,EAC7D,kBAAkB,CAAC,KAAK,EACxB,aAAa,CACd,CACF,CAAC;wBACF,MAAM;qBACP;iBACF;aACF;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAED,SAAS,WAAW,CAAC,QAAsB,EAAE,IAAU;IACrD,MAAM,cAAc,GAAI,IAAI,CAAC,GAAY,CAAC,QAAuB,CAAC;IAClE,MAAM,KAAK,GAAG,cAAc,CAAC,MAAM,CAAC;IACpC,MAAM,GAAG,GAAG,KAAK,GAAG,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC;IACjD,OAAO,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;AAC5E,CAAC;AAED,SAAS,OAAO,CAAC,IAAU,EAAE,IAAU;IACrC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjC,OAAO,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;AACxC,CAAC"}
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
import { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
import { Diagnostic } from 'vscode-languageserver-types';
|
||||
import { SingleYAMLDocument } from '../../parser/yaml-documents';
|
||||
export interface AdditionalValidator {
|
||||
validate(document: TextDocument, yamlDoc: SingleYAMLDocument): Diagnostic[];
|
||||
}
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Red Hat. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
export {};
|
||||
//# sourceMappingURL=types.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/languageservice/services/validation/types.ts"],"names":[],"mappings":"AAAA;;;gGAGgG"}
|
||||
Generated
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
import { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
import { Diagnostic } from 'vscode-languageserver-types';
|
||||
import { SingleYAMLDocument } from '../../parser/yaml-documents';
|
||||
import { AdditionalValidator } from './types';
|
||||
export declare class UnusedAnchorsValidator implements AdditionalValidator {
|
||||
validate(document: TextDocument, yamlDoc: SingleYAMLDocument): Diagnostic[];
|
||||
private getAnchorNode;
|
||||
}
|
||||
Generated
Vendored
+91
@@ -0,0 +1,91 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Red Hat. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { Diagnostic, DiagnosticSeverity, DiagnosticTag, Range } from 'vscode-languageserver-types';
|
||||
import { isAlias, isCollection, isNode, isScalar, visit, CST } from 'yaml';
|
||||
import { isCollectionItem } from '../../utils/yamlAstUtils';
|
||||
import * as l10n from '@vscode/l10n';
|
||||
export class UnusedAnchorsValidator {
|
||||
validate(document, yamlDoc) {
|
||||
const result = [];
|
||||
const anchors = new Set();
|
||||
const usedAnchors = new Set();
|
||||
const unIdentifiedAlias = new Set();
|
||||
const anchorParent = new Map();
|
||||
visit(yamlDoc.internalDocument, (key, node, path) => {
|
||||
if (!isNode(node)) {
|
||||
return;
|
||||
}
|
||||
if ((isCollection(node) || isScalar(node)) && node.anchor) {
|
||||
anchors.add(node);
|
||||
anchorParent.set(node, path[path.length - 1]);
|
||||
}
|
||||
if (isAlias(node)) {
|
||||
if (!node.resolve(yamlDoc.internalDocument)) {
|
||||
unIdentifiedAlias.add(node);
|
||||
}
|
||||
else {
|
||||
usedAnchors.add(node.resolve(yamlDoc.internalDocument));
|
||||
}
|
||||
}
|
||||
});
|
||||
for (const anchor of anchors) {
|
||||
if (!usedAnchors.has(anchor)) {
|
||||
const aToken = this.getAnchorNode(anchorParent.get(anchor), anchor);
|
||||
if (aToken) {
|
||||
const range = Range.create(document.positionAt(aToken.offset), document.positionAt(aToken.offset + aToken.source.length));
|
||||
const warningDiagnostic = Diagnostic.create(range, l10n.t('Unused anchor "{0}"', aToken.source), DiagnosticSeverity.Information, 0);
|
||||
warningDiagnostic.tags = [DiagnosticTag.Unnecessary];
|
||||
result.push(warningDiagnostic);
|
||||
}
|
||||
}
|
||||
}
|
||||
unIdentifiedAlias.forEach((node) => {
|
||||
const nodeRange = node.range;
|
||||
if (nodeRange) {
|
||||
const startOffset = nodeRange[0];
|
||||
const endOffset = nodeRange[1];
|
||||
const range = Range.create(document.positionAt(startOffset), document.positionAt(endOffset));
|
||||
const warningDiagnostic = Diagnostic.create(range, l10n.t('Unresolved alias "{0}"', node.toString()), DiagnosticSeverity.Information, 0);
|
||||
warningDiagnostic.tags = [DiagnosticTag.Unnecessary];
|
||||
result.push(warningDiagnostic);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
getAnchorNode(parentNode, node) {
|
||||
if (parentNode && parentNode.srcToken) {
|
||||
const token = parentNode.srcToken;
|
||||
if (isCollectionItem(token)) {
|
||||
return getAnchorFromCollectionItem(token);
|
||||
}
|
||||
else if (CST.isCollection(token)) {
|
||||
for (const t of token.items) {
|
||||
if (node.srcToken !== t.value)
|
||||
continue;
|
||||
const anchor = getAnchorFromCollectionItem(t);
|
||||
if (anchor) {
|
||||
return anchor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
function getAnchorFromCollectionItem(token) {
|
||||
for (const t of token.start) {
|
||||
if (t.type === 'anchor') {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
if (token.sep && Array.isArray(token.sep)) {
|
||||
for (const t of token.sep) {
|
||||
if (t.type === 'anchor') {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=unused-anchors.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"unused-anchors.js","sourceRoot":"","sources":["../../../../../src/languageservice/services/validation/unused-anchors.ts"],"names":[],"mappings":"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"}
|
||||
Generated
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
import { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
import { Diagnostic } from 'vscode-languageserver-types';
|
||||
import { SingleYAMLDocument } from '../../parser/yaml-documents';
|
||||
import { LanguageSettings } from '../../yamlLanguageService';
|
||||
import { AdditionalValidator } from './types';
|
||||
export declare class YAMLStyleValidator implements AdditionalValidator {
|
||||
private forbidSequence;
|
||||
private forbidMapping;
|
||||
constructor(settings: LanguageSettings);
|
||||
validate(document: TextDocument, yamlDoc: SingleYAMLDocument): Diagnostic[];
|
||||
private getRangeOf;
|
||||
}
|
||||
Generated
Vendored
+28
@@ -0,0 +1,28 @@
|
||||
import { Diagnostic, DiagnosticSeverity, Range } from 'vscode-languageserver-types';
|
||||
import { isMap, isSeq, visit } from 'yaml';
|
||||
import * as l10n from '@vscode/l10n';
|
||||
export class YAMLStyleValidator {
|
||||
constructor(settings) {
|
||||
this.forbidMapping = settings.flowMapping === 'forbid';
|
||||
this.forbidSequence = settings.flowSequence === 'forbid';
|
||||
}
|
||||
validate(document, yamlDoc) {
|
||||
const result = [];
|
||||
visit(yamlDoc.internalDocument, (key, node) => {
|
||||
if (this.forbidMapping && isMap(node) && node.srcToken?.type === 'flow-collection') {
|
||||
result.push(Diagnostic.create(this.getRangeOf(document, node.srcToken), l10n.t('Flow style mapping is forbidden'), DiagnosticSeverity.Error, 'flowMap'));
|
||||
}
|
||||
if (this.forbidSequence && isSeq(node) && node.srcToken?.type === 'flow-collection') {
|
||||
result.push(Diagnostic.create(this.getRangeOf(document, node.srcToken), l10n.t('Flow style sequence is forbidden'), DiagnosticSeverity.Error, 'flowSeq'));
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
getRangeOf(document, node) {
|
||||
const endOffset = node.end[0].offset;
|
||||
let endPosition = document.positionAt(endOffset);
|
||||
endPosition = { character: endPosition.character + 1, line: endPosition.line };
|
||||
return Range.create(document.positionAt(node.start.offset), endPosition);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=yaml-style.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"yaml-style.js","sourceRoot":"","sources":["../../../../../src/languageservice/services/validation/yaml-style.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AACpF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAK3C,OAAO,KAAK,IAAI,MAAM,cAAc,CAAC;AAErC,MAAM,OAAO,kBAAkB;IAI7B,YAAY,QAA0B;QACpC,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC,WAAW,KAAK,QAAQ,CAAC;QACvD,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC,YAAY,KAAK,QAAQ,CAAC;IAC3D,CAAC;IACD,QAAQ,CAAC,QAAsB,EAAE,OAA2B;QAC1D,MAAM,MAAM,GAAG,EAAE,CAAC;QAClB,KAAK,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;YAC5C,IAAI,IAAI,CAAC,aAAa,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,IAAI,KAAK,iBAAiB,EAAE;gBAClF,MAAM,CAAC,IAAI,CACT,UAAU,CAAC,MAAM,CACf,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,EACxC,IAAI,CAAC,CAAC,CAAC,iCAAiC,CAAC,EACzC,kBAAkB,CAAC,KAAK,EACxB,SAAS,CACV,CACF,CAAC;aACH;YACD,IAAI,IAAI,CAAC,cAAc,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,IAAI,KAAK,iBAAiB,EAAE;gBACnF,MAAM,CAAC,IAAI,CACT,UAAU,CAAC,MAAM,CACf,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,EACxC,IAAI,CAAC,CAAC,CAAC,kCAAkC,CAAC,EAC1C,kBAAkB,CAAC,KAAK,EACxB,SAAS,CACV,CACF,CAAC;aACH;QACH,CAAC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,UAAU,CAAC,QAAsB,EAAE,IAAoB;QAC7D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QACrC,IAAI,WAAW,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QACjD,WAAW,GAAG,EAAE,SAAS,EAAE,WAAW,CAAC,SAAS,GAAG,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC;QAC/E,OAAO,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC;IAC3E,CAAC;CACF"}
|
||||
Generated
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
import { CodeAction } from 'vscode-languageserver-types';
|
||||
import { ClientCapabilities, CodeActionParams } from 'vscode-languageserver-protocol';
|
||||
import { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
import { LanguageSettings } from '../yamlLanguageService';
|
||||
export declare class YamlCodeActions {
|
||||
private readonly clientCapabilities;
|
||||
private indentation;
|
||||
private lineWidth;
|
||||
constructor(clientCapabilities: ClientCapabilities);
|
||||
configure(settings: LanguageSettings, printWidth: number): void;
|
||||
getCodeAction(document: TextDocument, params: CodeActionParams): CodeAction[] | undefined;
|
||||
private getJumpToSchemaActions;
|
||||
private getTabToSpaceConverting;
|
||||
private getUnusedAnchorsDelete;
|
||||
private getConvertToBooleanActions;
|
||||
private getConvertToBlockStyleActions;
|
||||
private getConvertStringToBlockStyleActions;
|
||||
private getKeyOrderActions;
|
||||
/**
|
||||
* Check if diagnostic contains info for quick fix
|
||||
* Supports Enum/Const/Property mismatch
|
||||
*/
|
||||
private getPossibleQuickFixValues;
|
||||
private getQuickFixForPropertyOrValueMismatch;
|
||||
}
|
||||
Generated
Vendored
+342
@@ -0,0 +1,342 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Red Hat, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as l10n from '@vscode/l10n';
|
||||
import * as path from 'path';
|
||||
import { ErrorCode } from 'vscode-json-languageservice';
|
||||
import { CodeAction, CodeActionKind, Command, Position, Range, TextEdit, } from 'vscode-languageserver-types';
|
||||
import { CST, isMap, isSeq, isScalar, visit } from 'yaml';
|
||||
import { YamlCommands } from '../../commands';
|
||||
import { TextBuffer } from '../utils/textBuffer';
|
||||
import { toYamlStringScalar } from '../utils/yamlScalar';
|
||||
import { YAML_SOURCE } from '../parser/schemaValidation/baseValidator';
|
||||
import { getFirstNonWhitespaceCharacterAfterOffset } from '../utils/strings';
|
||||
import { matchOffsetToDocument } from '../utils/arrUtils';
|
||||
import { yamlDocumentsCache } from '../parser/yaml-documents';
|
||||
import { BlockStringRewriter } from '../utils/block-string-rewriter';
|
||||
import { FlowStyleRewriter } from '../utils/flow-style-rewriter';
|
||||
export class YamlCodeActions {
|
||||
constructor(clientCapabilities) {
|
||||
this.clientCapabilities = clientCapabilities;
|
||||
this.indentation = ' ';
|
||||
this.lineWidth = 80;
|
||||
}
|
||||
configure(settings, printWidth) {
|
||||
this.indentation = settings.indentation;
|
||||
this.lineWidth = printWidth;
|
||||
}
|
||||
getCodeAction(document, params) {
|
||||
if (!params.context.diagnostics) {
|
||||
return;
|
||||
}
|
||||
const result = [];
|
||||
result.push(...this.getConvertToBooleanActions(params.context.diagnostics, document));
|
||||
result.push(...this.getJumpToSchemaActions(params.context.diagnostics));
|
||||
result.push(...this.getTabToSpaceConverting(params.context.diagnostics, document));
|
||||
result.push(...this.getUnusedAnchorsDelete(params.context.diagnostics, document));
|
||||
result.push(...this.getConvertToBlockStyleActions(params.context.diagnostics, document));
|
||||
result.push(...this.getConvertStringToBlockStyleActions(params.range, document));
|
||||
result.push(...this.getKeyOrderActions(params.context.diagnostics, document));
|
||||
result.push(...this.getQuickFixForPropertyOrValueMismatch(params.context.diagnostics, document));
|
||||
return result;
|
||||
}
|
||||
getJumpToSchemaActions(diagnostics) {
|
||||
const isOpenTextDocumentEnabled = this.clientCapabilities?.window?.showDocument?.support ?? false;
|
||||
if (!isOpenTextDocumentEnabled) {
|
||||
return [];
|
||||
}
|
||||
const schemaUriToDiagnostic = new Map();
|
||||
for (const diagnostic of diagnostics) {
|
||||
const schemaUri = diagnostic.data?.schemaUri || [];
|
||||
for (const schemaUriStr of schemaUri) {
|
||||
if (schemaUriStr) {
|
||||
if (!schemaUriToDiagnostic.has(schemaUriStr)) {
|
||||
schemaUriToDiagnostic.set(schemaUriStr, []);
|
||||
}
|
||||
schemaUriToDiagnostic.get(schemaUriStr).push(diagnostic);
|
||||
}
|
||||
}
|
||||
}
|
||||
const result = [];
|
||||
for (const schemaUri of schemaUriToDiagnostic.keys()) {
|
||||
const action = CodeAction.create(l10n.t('Jump to schema location ({0})', path.basename(schemaUri)), Command.create('JumpToSchema', YamlCommands.JUMP_TO_SCHEMA, schemaUri));
|
||||
action.diagnostics = schemaUriToDiagnostic.get(schemaUri);
|
||||
result.push(action);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
getTabToSpaceConverting(diagnostics, document) {
|
||||
const result = [];
|
||||
const textBuff = new TextBuffer(document);
|
||||
const processedLine = [];
|
||||
for (const diag of diagnostics) {
|
||||
if (diag.message === 'Tabs are not allowed as indentation') {
|
||||
if (processedLine.includes(diag.range.start.line)) {
|
||||
continue;
|
||||
}
|
||||
const lineContent = textBuff.getLineContent(diag.range.start.line);
|
||||
let replacedTabs = 0;
|
||||
let newText = '';
|
||||
for (let i = diag.range.start.character; i <= diag.range.end.character; i++) {
|
||||
const char = lineContent.charAt(i);
|
||||
if (char !== '\t') {
|
||||
break;
|
||||
}
|
||||
replacedTabs++;
|
||||
newText += this.indentation;
|
||||
}
|
||||
processedLine.push(diag.range.start.line);
|
||||
let resultRange = diag.range;
|
||||
if (replacedTabs !== diag.range.end.character - diag.range.start.character) {
|
||||
resultRange = Range.create(diag.range.start, Position.create(diag.range.end.line, diag.range.start.character + replacedTabs));
|
||||
}
|
||||
result.push(CodeAction.create(l10n.t('Convert Tab to Spaces'), createWorkspaceEdit(document.uri, [TextEdit.replace(resultRange, newText)]), CodeActionKind.QuickFix));
|
||||
}
|
||||
}
|
||||
if (result.length !== 0) {
|
||||
const replaceEdits = [];
|
||||
for (let i = 0; i <= textBuff.getLineCount(); i++) {
|
||||
const lineContent = textBuff.getLineContent(i);
|
||||
let replacedTabs = 0;
|
||||
let newText = '';
|
||||
for (let j = 0; j < lineContent.length; j++) {
|
||||
const char = lineContent.charAt(j);
|
||||
if (char !== ' ' && char !== '\t') {
|
||||
if (replacedTabs !== 0) {
|
||||
replaceEdits.push(TextEdit.replace(Range.create(i, j - replacedTabs, i, j), newText));
|
||||
replacedTabs = 0;
|
||||
newText = '';
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (char === ' ' && replacedTabs !== 0) {
|
||||
replaceEdits.push(TextEdit.replace(Range.create(i, j - replacedTabs, i, j), newText));
|
||||
replacedTabs = 0;
|
||||
newText = '';
|
||||
continue;
|
||||
}
|
||||
if (char === '\t') {
|
||||
newText += this.indentation;
|
||||
replacedTabs++;
|
||||
}
|
||||
}
|
||||
// line contains only tabs
|
||||
if (replacedTabs !== 0) {
|
||||
replaceEdits.push(TextEdit.replace(Range.create(i, 0, i, textBuff.getLineLength(i)), newText));
|
||||
}
|
||||
}
|
||||
if (replaceEdits.length > 0) {
|
||||
result.push(CodeAction.create(l10n.t('Convert all Tabs to Spaces'), createWorkspaceEdit(document.uri, replaceEdits), CodeActionKind.QuickFix));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
getUnusedAnchorsDelete(diagnostics, document) {
|
||||
const result = [];
|
||||
const buffer = new TextBuffer(document);
|
||||
for (const diag of diagnostics) {
|
||||
if (diag.message.startsWith('Unused anchor') && diag.source === YAML_SOURCE) {
|
||||
const range = Range.create(diag.range.start, diag.range.end);
|
||||
const actual = buffer.getText(range);
|
||||
const lineContent = buffer.getLineContent(range.end.line);
|
||||
const lastWhitespaceChar = getFirstNonWhitespaceCharacterAfterOffset(lineContent, range.end.character);
|
||||
range.end.character = lastWhitespaceChar;
|
||||
const action = CodeAction.create(l10n.t('Delete unused anchor: {0}', actual), createWorkspaceEdit(document.uri, [TextEdit.del(range)]), CodeActionKind.QuickFix);
|
||||
action.diagnostics = [diag];
|
||||
result.push(action);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
getConvertToBooleanActions(diagnostics, document) {
|
||||
const results = [];
|
||||
for (const diagnostic of diagnostics) {
|
||||
if (diagnostic.message === 'Incorrect type. Expected "boolean".') {
|
||||
const value = document.getText(diagnostic.range).toLocaleLowerCase();
|
||||
if (value === '"true"' || value === '"false"' || value === "'true'" || value === "'false'") {
|
||||
const newValue = value.includes('true') ? 'true' : 'false';
|
||||
results.push(CodeAction.create(l10n.t('Convert to boolean'), createWorkspaceEdit(document.uri, [TextEdit.replace(diagnostic.range, newValue)]), CodeActionKind.QuickFix));
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
getConvertToBlockStyleActions(diagnostics, document) {
|
||||
const results = [];
|
||||
for (const diagnostic of diagnostics) {
|
||||
if (diagnostic.code === 'flowMap' || diagnostic.code === 'flowSeq') {
|
||||
const node = getNodeForDiagnostic(document, diagnostic);
|
||||
if (isMap(node.internalNode) || isSeq(node.internalNode)) {
|
||||
const blockTypeDescription = isMap(node.internalNode) ? 'map' : 'sequence';
|
||||
const rewriter = new FlowStyleRewriter(this.indentation);
|
||||
results.push(CodeAction.create(l10n.t('Convert to block style {0}', blockTypeDescription), createWorkspaceEdit(document.uri, [TextEdit.replace(diagnostic.range, rewriter.write(node))]), CodeActionKind.QuickFix));
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
getConvertStringToBlockStyleActions(range, document) {
|
||||
const yamlDocument = yamlDocumentsCache.getYamlDocument(document);
|
||||
const startOffset = range ? document.offsetAt(range.start) : 0;
|
||||
const endOffset = range ? document.offsetAt(range.end) : Infinity;
|
||||
const results = [];
|
||||
for (const singleYamlDocument of yamlDocument.documents) {
|
||||
const matchingNodes = [];
|
||||
visit(singleYamlDocument.internalDocument, (key, node) => {
|
||||
if (isScalar(node)) {
|
||||
if ((startOffset <= node.range[0] && node.range[2] <= endOffset) ||
|
||||
(node.range[0] <= startOffset && endOffset <= node.range[2])) {
|
||||
if (node.type === 'QUOTE_DOUBLE' || node.type === 'QUOTE_SINGLE') {
|
||||
if (typeof node.value === 'string' && (node.value.indexOf('\n') >= 0 || node.value.length > this.lineWidth)) {
|
||||
matchingNodes.push(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
for (const node of matchingNodes) {
|
||||
const range = Range.create(document.positionAt(node.range[0]), document.positionAt(node.range[1]));
|
||||
const rewriter = new BlockStringRewriter(this.indentation, this.lineWidth);
|
||||
const foldedBlockScalar = rewriter.writeFoldedBlockScalar(node);
|
||||
if (foldedBlockScalar !== null) {
|
||||
results.push(CodeAction.create(l10n.t('Convert string to folded block string'), createWorkspaceEdit(document.uri, [TextEdit.replace(range, foldedBlockScalar)]), CodeActionKind.Refactor));
|
||||
}
|
||||
const literalBlockScalar = rewriter.writeLiteralBlockScalar(node);
|
||||
if (literalBlockScalar !== null) {
|
||||
results.push(CodeAction.create(l10n.t('Convert string to literal block string'), createWorkspaceEdit(document.uri, [TextEdit.replace(range, literalBlockScalar)]), CodeActionKind.Refactor));
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
getKeyOrderActions(diagnostics, document) {
|
||||
const results = [];
|
||||
for (const diagnostic of diagnostics) {
|
||||
if (diagnostic?.code === 'mapKeyOrder') {
|
||||
let node = getNodeForDiagnostic(document, diagnostic);
|
||||
while (node && node.type !== 'object') {
|
||||
node = node.parent;
|
||||
}
|
||||
if (node && isMap(node.internalNode)) {
|
||||
const sorted = structuredClone(node.internalNode);
|
||||
const _getTrailingTokens = (value) => {
|
||||
if (!value)
|
||||
return;
|
||||
if (CST.isScalar(value)) {
|
||||
if (value.type === 'block-scalar') {
|
||||
value.props ?? (value.props = []);
|
||||
return value.props;
|
||||
}
|
||||
value.end ?? (value.end = []);
|
||||
return value.end;
|
||||
}
|
||||
if (value.type === 'flow-collection') {
|
||||
value.end ?? (value.end = []);
|
||||
return value.end;
|
||||
}
|
||||
if (value.type === 'block-map') {
|
||||
const lastItem = value.items[value.items.length - 1];
|
||||
return lastItem ? _getTrailingTokens(lastItem.value) : undefined;
|
||||
}
|
||||
return;
|
||||
};
|
||||
if ((sorted.srcToken.type === 'block-map' || sorted.srcToken.type === 'flow-collection') &&
|
||||
(node.internalNode.srcToken.type === 'block-map' || node.internalNode.srcToken.type === 'flow-collection')) {
|
||||
sorted.srcToken.items.sort((a, b) => {
|
||||
if (a.key && b.key && CST.isScalar(a.key) && CST.isScalar(b.key)) {
|
||||
return a.key.source.localeCompare(b.key.source);
|
||||
}
|
||||
if (!a.key && b.key) {
|
||||
return -1;
|
||||
}
|
||||
if (a.key && !b.key) {
|
||||
return 1;
|
||||
}
|
||||
if (!a.key && !b.key) {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
for (let i = 0; i < sorted.srcToken.items.length; i++) {
|
||||
const item = sorted.srcToken.items[i];
|
||||
const uItem = node.internalNode.srcToken.items[i];
|
||||
item.start = uItem.start;
|
||||
// strip leading blank lines so reordered entries stay one-per-line
|
||||
while (item.start?.[0]?.type === 'newline')
|
||||
item.start.shift();
|
||||
const itemTokens = _getTrailingTokens(item.value);
|
||||
const itemNewLineIndex = itemTokens?.findIndex((p) => p.type === 'newline') ?? -1;
|
||||
const uNewLineToken = _getTrailingTokens(uItem.value)?.find((p) => p.type === 'newline' && p.offset < node.offset + node.length) ??
|
||||
null;
|
||||
if (uNewLineToken && itemNewLineIndex < 0 && itemTokens) {
|
||||
itemTokens.push({ type: 'newline', indent: 0, offset: item.value.offset, source: '\n' });
|
||||
}
|
||||
if (!uNewLineToken && itemNewLineIndex > -1 && itemTokens) {
|
||||
itemTokens.splice(itemNewLineIndex, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
const replaceRange = Range.create(document.positionAt(node.offset), document.positionAt(node.offset + node.length));
|
||||
results.push(CodeAction.create(l10n.t('Fix key order for this map'), createWorkspaceEdit(document.uri, [TextEdit.replace(replaceRange, CST.stringify(sorted.srcToken))]), CodeActionKind.QuickFix));
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
/**
|
||||
* Check if diagnostic contains info for quick fix
|
||||
* Supports Enum/Const/Property mismatch
|
||||
*/
|
||||
getPossibleQuickFixValues(diagnostic) {
|
||||
if (typeof diagnostic.data !== 'object') {
|
||||
return;
|
||||
}
|
||||
if (diagnostic.code === ErrorCode.EnumValueMismatch &&
|
||||
'values' in diagnostic.data &&
|
||||
Array.isArray(diagnostic.data.values)) {
|
||||
return diagnostic.data.values;
|
||||
}
|
||||
else if (diagnostic.code === ErrorCode.PropertyExpected &&
|
||||
'properties' in diagnostic.data &&
|
||||
Array.isArray(diagnostic.data.properties)) {
|
||||
return diagnostic.data.properties;
|
||||
}
|
||||
}
|
||||
getQuickFixForPropertyOrValueMismatch(diagnostics, document) {
|
||||
const results = [];
|
||||
for (const diagnostic of diagnostics) {
|
||||
const values = this.getPossibleQuickFixValues(diagnostic);
|
||||
if (!values?.length) {
|
||||
continue;
|
||||
}
|
||||
for (const value of values) {
|
||||
const scalar = typeof value === 'string' ? toYamlStringScalar(value) : String(value);
|
||||
results.push(CodeAction.create(scalar, createWorkspaceEdit(document.uri, [TextEdit.replace(diagnostic.range, scalar)]), CodeActionKind.QuickFix));
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
function getNodeForDiagnostic(document, diagnostic) {
|
||||
const yamlDocuments = yamlDocumentsCache.getYamlDocument(document);
|
||||
const startOffset = document.offsetAt(diagnostic.range.start);
|
||||
const endOffset = document.offsetAt(diagnostic.range.end);
|
||||
const yamlDoc = matchOffsetToDocument(startOffset, yamlDocuments);
|
||||
let node = yamlDoc.getNodeFromOffset(startOffset);
|
||||
if (node && startOffset < endOffset && node.offset + node.length === startOffset) {
|
||||
const nodeInsideRange = yamlDoc.getNodeFromOffset(startOffset + 1);
|
||||
if (nodeInsideRange) {
|
||||
node = nodeInsideRange;
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
function createWorkspaceEdit(uri, edits) {
|
||||
const changes = {};
|
||||
changes[uri] = edits;
|
||||
const edit = {
|
||||
changes,
|
||||
};
|
||||
return edit;
|
||||
}
|
||||
//# sourceMappingURL=yamlCodeActions.js.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
import { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
import { CodeLens } from 'vscode-languageserver-types';
|
||||
import { YAMLSchemaService } from './yamlSchemaService';
|
||||
import { Telemetry } from '../telemetry';
|
||||
export declare class YamlCodeLens {
|
||||
private schemaService;
|
||||
private readonly telemetry?;
|
||||
constructor(schemaService: YAMLSchemaService, telemetry?: Telemetry);
|
||||
getCodeLens(document: TextDocument): Promise<CodeLens[]>;
|
||||
resolveCodeLens(param: CodeLens): PromiseLike<CodeLens> | CodeLens;
|
||||
}
|
||||
Generated
Vendored
+46
@@ -0,0 +1,46 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Red Hat, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { CodeLens, Range } from 'vscode-languageserver-types';
|
||||
import { YamlCommands } from '../../commands';
|
||||
import { yamlDocumentsCache } from '../parser/yaml-documents';
|
||||
import { getSchemaUrls } from '../utils/schemaUrls';
|
||||
import { getSchemaTitle } from '../utils/schemaUtils';
|
||||
export class YamlCodeLens {
|
||||
constructor(schemaService, telemetry) {
|
||||
this.schemaService = schemaService;
|
||||
this.telemetry = telemetry;
|
||||
}
|
||||
async getCodeLens(document) {
|
||||
const result = [];
|
||||
try {
|
||||
const yamlDocument = yamlDocumentsCache.getYamlDocument(document);
|
||||
let schemaUrls = new Map();
|
||||
for (const currentYAMLDoc of yamlDocument.documents) {
|
||||
const schema = await this.schemaService.getSchemaForResource(document.uri, currentYAMLDoc);
|
||||
if (schema?.schema) {
|
||||
// merge schemas from all docs to avoid duplicates
|
||||
schemaUrls = new Map([...getSchemaUrls(schema?.schema), ...schemaUrls]);
|
||||
}
|
||||
}
|
||||
for (const urlToSchema of schemaUrls) {
|
||||
const lens = CodeLens.create(Range.create(0, 0, 0, 0));
|
||||
lens.command = {
|
||||
title: getSchemaTitle(urlToSchema[1], urlToSchema[0]),
|
||||
command: YamlCommands.JUMP_TO_SCHEMA,
|
||||
arguments: [urlToSchema[0]],
|
||||
};
|
||||
result.push(lens);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
this.telemetry?.sendError('yaml.codeLens.error', err);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
resolveCodeLens(param) {
|
||||
return param;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=yamlCodeLens.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"yamlCodeLens.js","sourceRoot":"","sources":["../../../../src/languageservice/services/yamlCodeLens.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAGhG,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAI9D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,OAAO,YAAY;IACvB,YACU,aAAgC,EACvB,SAAqB;QAD9B,kBAAa,GAAb,aAAa,CAAmB;QACvB,cAAS,GAAT,SAAS,CAAY;IACrC,CAAC;IAEJ,KAAK,CAAC,WAAW,CAAC,QAAsB;QACtC,MAAM,MAAM,GAAG,EAAE,CAAC;QAClB,IAAI;YACF,MAAM,YAAY,GAAG,kBAAkB,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YAClE,IAAI,UAAU,GAAG,IAAI,GAAG,EAAsB,CAAC;YAC/C,KAAK,MAAM,cAAc,IAAI,YAAY,CAAC,SAAS,EAAE;gBACnD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;gBAC3F,IAAI,MAAM,EAAE,MAAM,EAAE;oBAClB,kDAAkD;oBAClD,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC;iBACzE;aACF;YACD,KAAK,MAAM,WAAW,IAAI,UAAU,EAAE;gBACpC,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBACvD,IAAI,CAAC,OAAO,GAAG;oBACb,KAAK,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;oBACrD,OAAO,EAAE,YAAY,CAAC,cAAc;oBACpC,SAAS,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;iBAC5B,CAAC;gBACF,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aACnB;SACF;QAAC,OAAO,GAAG,EAAE;YACZ,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAC;SACvD;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,eAAe,CAAC,KAAe;QAC7B,OAAO,KAAK,CAAC;IACf,CAAC;CACF"}
|
||||
Generated
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
import { Connection } from 'vscode-languageserver';
|
||||
import { CommandExecutor } from '../../languageserver/commandExecutor';
|
||||
export declare function registerCommands(commandExecutor: CommandExecutor, connection: Connection): void;
|
||||
Generated
Vendored
+46
@@ -0,0 +1,46 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Red Hat, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { YamlCommands } from '../../commands';
|
||||
import { URI } from 'vscode-uri';
|
||||
export function registerCommands(commandExecutor, connection) {
|
||||
commandExecutor.registerCommand(YamlCommands.JUMP_TO_SCHEMA, async (uri) => {
|
||||
if (!uri) {
|
||||
return;
|
||||
}
|
||||
const wsFolders = await connection.workspace.getWorkspaceFolders();
|
||||
if (uri.indexOf('://') < 0 && !uri.startsWith('/')) {
|
||||
if (wsFolders.length === 1) {
|
||||
const wsUri = URI.parse(wsFolders[0].uri);
|
||||
uri = wsUri.with({ path: wsUri.path + uri }).toString();
|
||||
}
|
||||
}
|
||||
else if (uri.startsWith('file://') && wsFolders.length === 1 && URI.parse(wsFolders[0].uri).scheme != 'file') {
|
||||
const wsUri = URI.parse(wsFolders[0].uri);
|
||||
const pathFromUri = URI.parse(uri).path;
|
||||
uri = wsUri.with({ path: pathFromUri }).toString();
|
||||
}
|
||||
else if (!uri.startsWith('file') && !/^[a-z]:[\\/]/i.test(uri)) {
|
||||
// if uri points to local file of its a windows path
|
||||
const origUri = URI.parse(uri);
|
||||
const customUri = URI.from({
|
||||
scheme: 'json-schema',
|
||||
authority: origUri.authority,
|
||||
path: origUri.path.endsWith('.json') ? origUri.path : origUri.path + '.json',
|
||||
fragment: uri,
|
||||
});
|
||||
uri = customUri.toString();
|
||||
}
|
||||
// test if uri is windows path, ie starts with 'c:\' and convert to URI
|
||||
if (/^[a-z]:[\\/]/i.test(uri)) {
|
||||
const winUri = URI.file(uri);
|
||||
uri = winUri.toString();
|
||||
}
|
||||
const result = await connection.window.showDocument({ uri: uri, external: false, takeFocus: true });
|
||||
if (!result) {
|
||||
connection.window.showErrorMessage(`Cannot open ${uri}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=yamlCommands.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"yamlCommands.js","sourceRoot":"","sources":["../../../../src/languageservice/services/yamlCommands.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAGhG,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEjC,MAAM,UAAU,gBAAgB,CAAC,eAAgC,EAAE,UAAsB;IACvF,eAAe,CAAC,eAAe,CAAC,YAAY,CAAC,cAAc,EAAE,KAAK,EAAE,GAAW,EAAE,EAAE;QACjF,IAAI,CAAC,GAAG,EAAE;YACR,OAAO;SACR;QACD,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,mBAAmB,EAAE,CAAC;QAEnE,IAAI,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;YAClD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE;gBAC1B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBAC1C,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,GAAG,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;aACzD;SACF;aAAM,IAAI,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,MAAM,EAAE;YAC9G,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAC1C,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACxC,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;SACpD;aAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;YAChE,oDAAoD;YACpD,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/B,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC;gBACzB,MAAM,EAAE,aAAa;gBACrB,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,GAAG,OAAO;gBAC5E,QAAQ,EAAE,GAAG;aACd,CAAC,CAAC;YACH,GAAG,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;SAC5B;QAED,uEAAuE;QACvE,IAAI,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;YAC7B,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7B,GAAG,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;SACzB;QAED,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpG,IAAI,CAAC,MAAM,EAAE;YACX,UAAU,CAAC,MAAM,CAAC,gBAAgB,CAAC,eAAe,GAAG,EAAE,CAAC,CAAC;SAC1D;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
||||
Generated
Vendored
+77
@@ -0,0 +1,77 @@
|
||||
import { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
import { ClientCapabilities } from 'vscode-languageserver';
|
||||
import { CompletionItem as CompletionItemBase, CompletionList, Position } from 'vscode-languageserver-types';
|
||||
import { Telemetry } from '../telemetry';
|
||||
import { YamlDocuments } from '../parser/yaml-documents';
|
||||
import { LanguageSettings } from '../yamlLanguageService';
|
||||
import { YAMLSchemaService } from './yamlSchemaService';
|
||||
import { JSONSchema } from '../jsonSchema';
|
||||
import { SettingsState } from '../../yamlSettings';
|
||||
interface ParentCompletionItemOptions {
|
||||
schema: JSONSchema;
|
||||
indent?: string;
|
||||
insertTexts?: string[];
|
||||
}
|
||||
interface CompletionItem extends CompletionItemBase {
|
||||
parent?: ParentCompletionItemOptions;
|
||||
}
|
||||
export declare class YamlCompletion {
|
||||
private schemaService;
|
||||
private clientCapabilities;
|
||||
private yamlDocument;
|
||||
private readonly telemetry?;
|
||||
private customTags;
|
||||
private completionEnabled;
|
||||
private configuredIndentation;
|
||||
private yamlVersion;
|
||||
private isSingleQuote;
|
||||
private indentation;
|
||||
private arrayPrefixIndentation;
|
||||
private supportsMarkdown;
|
||||
private disableDefaultProperties;
|
||||
private parentSkeletonSelectedFirst;
|
||||
constructor(schemaService: YAMLSchemaService, clientCapabilities: ClientCapabilities, yamlDocument: YamlDocuments, telemetry?: Telemetry);
|
||||
configure(languageSettings: LanguageSettings, yamlSettings?: SettingsState): void;
|
||||
doComplete(document: TextDocument, position: Position, isKubernetes?: boolean, doComplete?: boolean): Promise<CompletionList>;
|
||||
updateCompletionText(completionItem: CompletionItem, text: string): void;
|
||||
mergeSimpleInsertTexts(label: string, existingText: string, addingText: string, oneOfSchema: boolean): string | undefined;
|
||||
getValuesFromInsertText(insertText: string): string[];
|
||||
private finalizeParentCompletion;
|
||||
private createTempObjNode;
|
||||
private addPropertyCompletions;
|
||||
private getValueCompletions;
|
||||
private addArrayItemValueCompletion;
|
||||
private getInsertTextForProperty;
|
||||
private getInsertTextForObject;
|
||||
private getInsertTextForArray;
|
||||
private getInsertTextForGuessedValue;
|
||||
private getInsertTextForPlainText;
|
||||
private getInsertTextForValue;
|
||||
private getInsertTemplateForValue;
|
||||
private addSchemaValueCompletions;
|
||||
private collectTypes;
|
||||
private addDefaultValueCompletions;
|
||||
private addEnumValueCompletions;
|
||||
private getLabelForValue;
|
||||
private collectDefaultSnippets;
|
||||
private getInsertTextForSnippetValue;
|
||||
private addBooleanValueCompletion;
|
||||
private addNullValueCompletion;
|
||||
private getLabelForSnippetValue;
|
||||
private getCustomTagValueCompletions;
|
||||
private addCustomTagValueCompletion;
|
||||
private getDocumentationWithMarkdownText;
|
||||
private getSuggestionKind;
|
||||
private getCurrentWord;
|
||||
private fromMarkup;
|
||||
private doesSupportMarkdown;
|
||||
private findItemAtOffset;
|
||||
private getPropertyNamesCandidates;
|
||||
getQuote(): string;
|
||||
/**
|
||||
* simplify `{$1:value}` to `value`
|
||||
*/
|
||||
evaluateTab1Symbol(value: string): string;
|
||||
isParentCompletionItem(item: CompletionItemBase): item is CompletionItem;
|
||||
}
|
||||
export {};
|
||||
Generated
Vendored
+1498
File diff suppressed because it is too large
Load Diff
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
import { DefinitionParams } from 'vscode-languageserver-protocol';
|
||||
import { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
import { DefinitionLink } from 'vscode-languageserver-types';
|
||||
import { Telemetry } from '../telemetry';
|
||||
export declare class YamlDefinition {
|
||||
private readonly telemetry?;
|
||||
constructor(telemetry?: Telemetry);
|
||||
getDefinition(document: TextDocument, params: DefinitionParams): DefinitionLink[] | undefined;
|
||||
}
|
||||
Generated
Vendored
+37
@@ -0,0 +1,37 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Red Hat, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { LocationLink, Range } from 'vscode-languageserver-types';
|
||||
import { isAlias } from 'yaml';
|
||||
import { yamlDocumentsCache } from '../parser/yaml-documents';
|
||||
import { matchOffsetToDocument } from '../utils/arrUtils';
|
||||
import { TextBuffer } from '../utils/textBuffer';
|
||||
export class YamlDefinition {
|
||||
constructor(telemetry) {
|
||||
this.telemetry = telemetry;
|
||||
}
|
||||
getDefinition(document, params) {
|
||||
try {
|
||||
const yamlDocument = yamlDocumentsCache.getYamlDocument(document);
|
||||
const offset = document.offsetAt(params.position);
|
||||
const currentDoc = matchOffsetToDocument(offset, yamlDocument);
|
||||
if (currentDoc) {
|
||||
const [node] = currentDoc.getNodeFromPosition(offset, new TextBuffer(document));
|
||||
if (node && isAlias(node)) {
|
||||
const defNode = node.resolve(currentDoc.internalDocument);
|
||||
if (defNode && defNode.range) {
|
||||
const targetRange = Range.create(document.positionAt(defNode.range[0]), document.positionAt(defNode.range[2]));
|
||||
const selectionRange = Range.create(document.positionAt(defNode.range[0]), document.positionAt(defNode.range[1]));
|
||||
return [LocationLink.create(document.uri, targetRange, selectionRange)];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
this.telemetry?.sendError('yaml.definition.error', err);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=yamlDefinition.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"yamlDefinition.js","sourceRoot":"","sources":["../../../../src/languageservice/services/yamlDefinition.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAIhG,OAAO,EAAkB,YAAY,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAClF,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,OAAO,cAAc;IACzB,YAA6B,SAAqB;QAArB,cAAS,GAAT,SAAS,CAAY;IAAG,CAAC;IAEtD,aAAa,CAAC,QAAsB,EAAE,MAAwB;QAC5D,IAAI;YACF,MAAM,YAAY,GAAG,kBAAkB,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YAClE,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAClD,MAAM,UAAU,GAAG,qBAAqB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;YAC/D,IAAI,UAAU,EAAE;gBACd,MAAM,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,mBAAmB,CAAC,MAAM,EAAE,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAChF,IAAI,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE;oBACzB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;oBAC1D,IAAI,OAAO,IAAI,OAAO,CAAC,KAAK,EAAE;wBAC5B,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBAC/G,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBAClH,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC;qBACzE;iBACF;aACF;SACF;QAAC,OAAO,GAAG,EAAE;YACZ,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;SACzD;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;CACF"}
|
||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
import { FoldingRange } from 'vscode-languageserver-types';
|
||||
import { FoldingRangesContext } from '../yamlTypes';
|
||||
import { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
export declare function getFoldingRanges(document: TextDocument, context: FoldingRangesContext): FoldingRange[] | undefined;
|
||||
Generated
Vendored
+62
@@ -0,0 +1,62 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Red Hat, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { FoldingRange, Range } from 'vscode-languageserver-types';
|
||||
import { yamlDocumentsCache } from '../parser/yaml-documents';
|
||||
export function getFoldingRanges(document, context) {
|
||||
if (!document) {
|
||||
return;
|
||||
}
|
||||
const result = [];
|
||||
const doc = yamlDocumentsCache.getYamlDocument(document);
|
||||
for (const ymlDoc of doc.documents) {
|
||||
if (doc.documents.length > 1) {
|
||||
result.push(createNormalizedFolding(document, ymlDoc.root));
|
||||
}
|
||||
ymlDoc.visit((node) => {
|
||||
if (node.type === 'object' && node.parent?.type === 'array') {
|
||||
result.push(createNormalizedFolding(document, node));
|
||||
}
|
||||
if (node.type === 'property' && node.valueNode) {
|
||||
switch (node.valueNode.type) {
|
||||
case 'array':
|
||||
case 'object':
|
||||
result.push(createNormalizedFolding(document, node));
|
||||
break;
|
||||
case 'string': {
|
||||
// check if it is a multi-line string
|
||||
const nodePosn = document.positionAt(node.offset);
|
||||
const valuePosn = document.positionAt(node.valueNode.offset + node.valueNode.length);
|
||||
if (nodePosn.line !== valuePosn.line) {
|
||||
result.push(createNormalizedFolding(document, node));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
const rangeLimit = context && context.rangeLimit;
|
||||
if (typeof rangeLimit !== 'number' || result.length <= rangeLimit) {
|
||||
return result;
|
||||
}
|
||||
if (context && context.onRangeLimitExceeded) {
|
||||
context.onRangeLimitExceeded(document.uri);
|
||||
}
|
||||
return result.slice(0, context.rangeLimit);
|
||||
}
|
||||
function createNormalizedFolding(document, node) {
|
||||
const startPos = document.positionAt(node.offset);
|
||||
let endPos = document.positionAt(node.offset + node.length);
|
||||
const textFragment = document.getText(Range.create(startPos, endPos));
|
||||
const newLength = textFragment.length - textFragment.trimRight().length;
|
||||
if (newLength > 0) {
|
||||
endPos = document.positionAt(node.offset + node.length - newLength);
|
||||
}
|
||||
return FoldingRange.create(startPos.line, endPos.line, startPos.character, endPos.character);
|
||||
}
|
||||
//# sourceMappingURL=yamlFolding.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"yamlFolding.js","sourceRoot":"","sources":["../../../../src/languageservice/services/yamlFolding.ts"],"names":[],"mappings":"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"}
|
||||
Generated
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
import { TextEdit, FormattingOptions } from 'vscode-languageserver-types';
|
||||
import { CustomFormatterOptions, LanguageSettings } from '../yamlLanguageService';
|
||||
import { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
export declare class YAMLFormatter {
|
||||
private formatterEnabled;
|
||||
configure(shouldFormat: LanguageSettings): void;
|
||||
format(document: TextDocument, options?: Partial<FormattingOptions> & CustomFormatterOptions): Promise<TextEdit[]>;
|
||||
}
|
||||
Generated
Vendored
+46
@@ -0,0 +1,46 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) Adam Voss. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { Range, Position, TextEdit } from 'vscode-languageserver-types';
|
||||
import * as yamlPlugin from 'prettier/plugins/yaml';
|
||||
import * as estreePlugin from 'prettier/plugins/estree';
|
||||
import { format } from 'prettier/standalone';
|
||||
export class YAMLFormatter {
|
||||
constructor() {
|
||||
this.formatterEnabled = true;
|
||||
}
|
||||
configure(shouldFormat) {
|
||||
if (shouldFormat) {
|
||||
this.formatterEnabled = shouldFormat.format;
|
||||
}
|
||||
}
|
||||
async format(document, options = {}) {
|
||||
if (!this.formatterEnabled) {
|
||||
return [];
|
||||
}
|
||||
try {
|
||||
const text = document.getText();
|
||||
const prettierOptions = {
|
||||
parser: 'yaml',
|
||||
plugins: [yamlPlugin, estreePlugin],
|
||||
// --- FormattingOptions ---
|
||||
tabWidth: options.tabWidth || options.tabSize,
|
||||
// --- CustomFormatterOptions ---
|
||||
singleQuote: options.singleQuote,
|
||||
bracketSpacing: options.bracketSpacing,
|
||||
// 'preserve' is the default for Options.proseWrap. See also server.ts
|
||||
proseWrap: 'always' === options.proseWrap ? 'always' : 'never' === options.proseWrap ? 'never' : 'preserve',
|
||||
printWidth: options.printWidth,
|
||||
trailingComma: options.trailingComma === false ? 'none' : 'all',
|
||||
};
|
||||
const formatted = await format(text, prettierOptions);
|
||||
return [TextEdit.replace(Range.create(Position.create(0, 0), document.positionAt(text.length)), formatted)];
|
||||
}
|
||||
catch (error) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=yamlFormatter.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"yamlFormatter.js","sourceRoot":"","sources":["../../../../src/languageservice/services/yamlFormatter.ts"],"names":[],"mappings":"AAAA;;;;gGAIgG;AAEhG,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAqB,MAAM,6BAA6B,CAAC;AAG3F,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,YAAY,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG7C,MAAM,OAAO,aAAa;IAA1B;QACU,qBAAgB,GAAG,IAAI,CAAC;IA0ClC,CAAC;IAxCQ,SAAS,CAAC,YAA8B;QAC7C,IAAI,YAAY,EAAE;YAChB,IAAI,CAAC,gBAAgB,GAAG,YAAY,CAAC,MAAM,CAAC;SAC7C;IACH,CAAC;IAEM,KAAK,CAAC,MAAM,CACjB,QAAsB,EACtB,UAA+D,EAAE;QAEjE,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;YAC1B,OAAO,EAAE,CAAC;SACX;QAED,IAAI;YACF,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;YAEhC,MAAM,eAAe,GAAY;gBAC/B,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,CAAC,UAAU,EAAE,YAAY,CAAC;gBAEnC,4BAA4B;gBAC5B,QAAQ,EAAG,OAAO,CAAC,QAAmB,IAAI,OAAO,CAAC,OAAO;gBAEzD,iCAAiC;gBACjC,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,sEAAsE;gBACtE,SAAS,EAAE,QAAQ,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU;gBAC3G,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,aAAa,EAAE,OAAO,CAAC,aAAa,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK;aAChE,CAAC;YAEF,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;YAEtD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;SAC7G;QAAC,OAAO,KAAK,EAAE;YACd,OAAO,EAAE,CAAC;SACX;IACH,CAAC;CACF"}
|
||||
Generated
Vendored
+47
@@ -0,0 +1,47 @@
|
||||
import { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
import { Hover, Position } from 'vscode-languageserver-types';
|
||||
import { Telemetry } from '../telemetry';
|
||||
import { LanguageSettings } from '../yamlLanguageService';
|
||||
import { YAMLSchemaService } from './yamlSchemaService';
|
||||
export declare class YAMLHover {
|
||||
private readonly telemetry?;
|
||||
private shouldHover;
|
||||
private shouldHoverAnchor;
|
||||
private indentation;
|
||||
private schemaService;
|
||||
constructor(schemaService: YAMLSchemaService, telemetry?: Telemetry);
|
||||
configure(languageSettings: LanguageSettings): void;
|
||||
doHover(document: TextDocument, position: Position, isKubernetes?: boolean): Promise<Hover | null>;
|
||||
private getHover;
|
||||
/**
|
||||
* Resolves merge keys (<<) and anchors recursively in an object node
|
||||
* @param node The object AST node to resolve
|
||||
* @param doc The YAML document for resolving anchors
|
||||
* @param currentRecursionLevel Current recursion level (default: 0)
|
||||
* @returns A plain JavaScript object with all merges resolved
|
||||
*/
|
||||
private resolveMergeKeys;
|
||||
/**
|
||||
* Resolves a merge value (which might be an alias) and recursively resolves its merge keys
|
||||
* @param node The AST node that might be an alias or object
|
||||
* @param doc The YAML document for resolving anchors
|
||||
* @param currentRecursionLevel Current recursion level
|
||||
* @returns The resolved value
|
||||
*/
|
||||
private resolveMergeValue;
|
||||
/**
|
||||
* Converts an AST node to a plain JavaScript value
|
||||
* @param node The AST node to convert
|
||||
* @param doc The YAML document for resolving anchors
|
||||
* @param currentRecursionLevel Current recursion level
|
||||
* @returns The converted value
|
||||
*/
|
||||
private astNodeToValue;
|
||||
/**
|
||||
* Converts a YAML Node to a plain JavaScript value
|
||||
* @param node The YAML node to convert
|
||||
* @returns The converted value
|
||||
*/
|
||||
private nodeToValue;
|
||||
private toMarkdown;
|
||||
}
|
||||
+366
@@ -0,0 +1,366 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Red Hat, Inc. 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.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as l10n from '@vscode/l10n';
|
||||
import * as path from 'path';
|
||||
import { MarkupKind, Range } from 'vscode-languageserver-types';
|
||||
import { URI } from 'vscode-uri';
|
||||
import { isAlias, isMap, isSeq, stringify as stringifyYAML } from 'yaml';
|
||||
import { setKubernetesParserOption } from '../parser/isKubernetes';
|
||||
import { getNodeValue } from '../parser/astNodeUtils';
|
||||
import { yamlDocumentsCache } from '../parser/yaml-documents';
|
||||
import { matchOffsetToDocument } from '../utils/arrUtils';
|
||||
import { toYamlStringScalar } from '../utils/yamlScalar';
|
||||
export class YAMLHover {
|
||||
constructor(schemaService, telemetry) {
|
||||
this.telemetry = telemetry;
|
||||
this.shouldHover = true;
|
||||
this.schemaService = schemaService;
|
||||
}
|
||||
configure(languageSettings) {
|
||||
if (languageSettings) {
|
||||
this.shouldHover = languageSettings.hover;
|
||||
this.shouldHoverAnchor = languageSettings.hoverAnchor;
|
||||
this.indentation = languageSettings.indentation;
|
||||
}
|
||||
}
|
||||
doHover(document, position, isKubernetes = false) {
|
||||
try {
|
||||
if (!this.shouldHover || !document) {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
const doc = yamlDocumentsCache.getYamlDocument(document);
|
||||
const offset = document.offsetAt(position);
|
||||
const currentDoc = matchOffsetToDocument(offset, doc);
|
||||
if (currentDoc === null) {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
setKubernetesParserOption(doc.documents, isKubernetes);
|
||||
const currentDocIndex = doc.documents.indexOf(currentDoc);
|
||||
currentDoc.currentDocIndex = currentDocIndex;
|
||||
return this.getHover(document, position, currentDoc);
|
||||
}
|
||||
catch (error) {
|
||||
this.telemetry?.sendError('yaml.hover.error', error);
|
||||
}
|
||||
}
|
||||
// method copied from https://github.com/microsoft/vscode-json-languageservice/blob/2ea5ad3d2ffbbe40dea11cfe764a502becf113ce/src/services/jsonHover.ts#L23
|
||||
getHover(document, position, doc) {
|
||||
const offset = document.offsetAt(position);
|
||||
let node = doc.getNodeFromOffset(offset);
|
||||
if (!node ||
|
||||
((node.type === 'object' || node.type === 'array') && offset > node.offset + 1 && offset < node.offset + node.length - 1)) {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
const hoverRangeNode = node;
|
||||
// use the property description when hovering over an object key
|
||||
if (node.type === 'string') {
|
||||
const parent = node.parent;
|
||||
if (parent && parent.type === 'property' && parent.keyNode === node) {
|
||||
node = parent.valueNode;
|
||||
if (!node) {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
const hoverRange = Range.create(document.positionAt(hoverRangeNode.offset), document.positionAt(hoverRangeNode.offset + hoverRangeNode.length));
|
||||
const createHover = (contents) => {
|
||||
const markupContent = {
|
||||
kind: MarkupKind.Markdown,
|
||||
value: contents,
|
||||
};
|
||||
const result = {
|
||||
contents: markupContent,
|
||||
range: hoverRange,
|
||||
};
|
||||
return result;
|
||||
};
|
||||
if (this.shouldHoverAnchor && node.type === 'property' && node.valueNode) {
|
||||
if (node.valueNode.type === 'object') {
|
||||
const resolved = this.resolveMergeKeys(node.valueNode, doc);
|
||||
const contents = '```yaml\n' + stringifyYAML(resolved, null, 2) + '\n```';
|
||||
return Promise.resolve(createHover(contents));
|
||||
}
|
||||
}
|
||||
const removePipe = (value) => {
|
||||
return value.replace(/\s\|\|\s*$/, '');
|
||||
};
|
||||
return this.schemaService.getSchemaForResource(document.uri, doc).then((schema) => {
|
||||
if (schema && node && !schema.errors.length) {
|
||||
const matchingSchemas = doc.getMatchingSchemas(schema.schema, node.offset);
|
||||
let title = undefined;
|
||||
let markdownDescription = undefined;
|
||||
let markdownEnumDescriptions = [];
|
||||
const markdownExamples = [];
|
||||
const markdownEnums = [];
|
||||
let enumIdx = undefined;
|
||||
matchingSchemas.every((s) => {
|
||||
if ((s.node === node || (node.type === 'property' && node.valueNode === s.node)) && !s.inverted && s.schema) {
|
||||
title = title || s.schema.title || s.schema.closestTitle;
|
||||
markdownDescription = markdownDescription || s.schema.markdownDescription || this.toMarkdown(s.schema.description);
|
||||
if (s.schema.enum) {
|
||||
enumIdx = s.schema.enum.indexOf(getNodeValue(node));
|
||||
if (s.schema.markdownEnumDescriptions) {
|
||||
markdownEnumDescriptions = s.schema.markdownEnumDescriptions;
|
||||
}
|
||||
else if (s.schema.enumDescriptions) {
|
||||
markdownEnumDescriptions = s.schema.enumDescriptions.map(this.toMarkdown, this);
|
||||
}
|
||||
else {
|
||||
markdownEnumDescriptions = [];
|
||||
}
|
||||
s.schema.enum.forEach((enumValue, idx) => {
|
||||
var _a;
|
||||
enumValue = typeof enumValue === 'string' ? toYamlStringScalar(enumValue, false) : JSON.stringify(enumValue);
|
||||
//insert only if the value is not present yet (avoiding duplicates)
|
||||
//but it also adds or keeps the description of the enum value
|
||||
const foundIdx = markdownEnums.findIndex((me) => me.value === enumValue);
|
||||
if (foundIdx < 0) {
|
||||
markdownEnums.push({
|
||||
value: enumValue,
|
||||
description: markdownEnumDescriptions[idx],
|
||||
});
|
||||
}
|
||||
else {
|
||||
(_a = markdownEnums[foundIdx]).description || (_a.description = markdownEnumDescriptions[idx]);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (s.schema.anyOf && isAllSchemasMatched(node, matchingSchemas, s.schema)) {
|
||||
//if append title and description of all matched schemas on hover
|
||||
title = '';
|
||||
markdownDescription = s.schema.description ? s.schema.description + '\n' : '';
|
||||
s.schema.anyOf.forEach((childSchema, index) => {
|
||||
title += childSchema.title || s.schema.closestTitle || '';
|
||||
markdownDescription += childSchema.markdownDescription || this.toMarkdown(childSchema.description) || '';
|
||||
if (index !== s.schema.anyOf.length - 1) {
|
||||
title += ' || ';
|
||||
markdownDescription += ' || ';
|
||||
}
|
||||
});
|
||||
title = removePipe(title);
|
||||
markdownDescription = removePipe(markdownDescription);
|
||||
}
|
||||
if (s.schema.examples) {
|
||||
s.schema.examples.forEach((example) => {
|
||||
markdownExamples.push(stringifyYAML(example, null, 2));
|
||||
});
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
let result = '';
|
||||
if (title) {
|
||||
result = '#### ' + this.toMarkdown(title);
|
||||
}
|
||||
if (markdownDescription) {
|
||||
result = ensureLineBreak(result);
|
||||
result += markdownDescription;
|
||||
}
|
||||
if (markdownEnums.length !== 0) {
|
||||
result = ensureLineBreak(result);
|
||||
result += l10n.t('Allowed Values:') + '\n\n';
|
||||
if (enumIdx) {
|
||||
markdownEnums.unshift(markdownEnums.splice(enumIdx, 1)[0]);
|
||||
}
|
||||
markdownEnums.forEach((me) => {
|
||||
if (me.description) {
|
||||
result += `* \`${toMarkdownCodeBlock(me.value)}\`: ${me.description}\n`;
|
||||
}
|
||||
else {
|
||||
result += `* \`${toMarkdownCodeBlock(me.value)}\`\n`;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (markdownExamples.length !== 0) {
|
||||
markdownExamples.forEach((example) => {
|
||||
result = ensureLineBreak(result);
|
||||
result += l10n.t('Example:') + '\n\n';
|
||||
result += `\`\`\`yaml\n${example}\`\`\`\n`;
|
||||
});
|
||||
}
|
||||
if (result.length > 0 && schema.schema.url) {
|
||||
result = ensureLineBreak(result);
|
||||
result += l10n.t('Source: [{0}]({1})', getSchemaName(schema.schema), schema.schema.url);
|
||||
}
|
||||
return createHover(result);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Resolves merge keys (<<) and anchors recursively in an object node
|
||||
* @param node The object AST node to resolve
|
||||
* @param doc The YAML document for resolving anchors
|
||||
* @param currentRecursionLevel Current recursion level (default: 0)
|
||||
* @returns A plain JavaScript object with all merges resolved
|
||||
*/
|
||||
resolveMergeKeys(node, doc, currentRecursionLevel = 0) {
|
||||
const result = {};
|
||||
const unprocessedProperties = [...node.properties];
|
||||
while (unprocessedProperties.length > 0) {
|
||||
const propertyNode = unprocessedProperties.shift();
|
||||
const key = propertyNode.keyNode.value;
|
||||
if (key === '<<' && propertyNode.valueNode) {
|
||||
// Handle merge key
|
||||
const mergeValue = this.resolveMergeValue(propertyNode.valueNode, doc, currentRecursionLevel + 1);
|
||||
if (mergeValue && typeof mergeValue === 'object' && !Array.isArray(mergeValue)) {
|
||||
// Merge properties from the resolved value
|
||||
const mergeKeys = Object.keys(mergeValue);
|
||||
for (const mergeKey of mergeKeys) {
|
||||
result[mergeKey] = mergeValue[mergeKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Regular property
|
||||
result[key] = this.astNodeToValue(propertyNode.valueNode, doc, currentRecursionLevel);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Resolves a merge value (which might be an alias) and recursively resolves its merge keys
|
||||
* @param node The AST node that might be an alias or object
|
||||
* @param doc The YAML document for resolving anchors
|
||||
* @param currentRecursionLevel Current recursion level
|
||||
* @returns The resolved value
|
||||
*/
|
||||
resolveMergeValue(node, doc, currentRecursionLevel) {
|
||||
const MAX_MERGE_RECURSION_LEVEL = 10;
|
||||
// Check if we've exceeded max recursion level
|
||||
if (currentRecursionLevel >= MAX_MERGE_RECURSION_LEVEL) {
|
||||
return { '<<': node.parent.internalNode['value'] + ' (recursion limit reached)' };
|
||||
}
|
||||
// If it's an object node, resolve its merge keys
|
||||
if (node.type === 'object') {
|
||||
return this.resolveMergeKeys(node, doc, currentRecursionLevel);
|
||||
}
|
||||
// Otherwise, convert to value
|
||||
return this.astNodeToValue(node, doc, currentRecursionLevel);
|
||||
}
|
||||
/**
|
||||
* Converts an AST node to a plain JavaScript value
|
||||
* @param node The AST node to convert
|
||||
* @param doc The YAML document for resolving anchors
|
||||
* @param currentRecursionLevel Current recursion level
|
||||
* @returns The converted value
|
||||
*/
|
||||
astNodeToValue(node, doc, currentRecursionLevel) {
|
||||
if (!node) {
|
||||
return null;
|
||||
}
|
||||
switch (node.type) {
|
||||
case 'object': {
|
||||
return this.resolveMergeKeys(node, doc, currentRecursionLevel);
|
||||
}
|
||||
case 'array': {
|
||||
return node.children.map((child) => this.astNodeToValue(child, doc, currentRecursionLevel));
|
||||
}
|
||||
case 'string':
|
||||
case 'number':
|
||||
case 'boolean':
|
||||
case 'null': {
|
||||
return node.value;
|
||||
}
|
||||
default: {
|
||||
return this.nodeToValue(node.internalNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Converts a YAML Node to a plain JavaScript value
|
||||
* @param node The YAML node to convert
|
||||
* @returns The converted value
|
||||
*/
|
||||
nodeToValue(node) {
|
||||
if (isAlias(node)) {
|
||||
return node.source;
|
||||
}
|
||||
if (isMap(node)) {
|
||||
const result = {};
|
||||
for (const pair of node.items) {
|
||||
if (pair.key && pair.value) {
|
||||
const key = this.nodeToValue(pair.key);
|
||||
const value = this.nodeToValue(pair.value);
|
||||
if (typeof key === 'string') {
|
||||
result[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (isSeq(node)) {
|
||||
return node.items.map((item) => this.nodeToValue(item));
|
||||
}
|
||||
return node.value;
|
||||
}
|
||||
// copied from https://github.com/microsoft/vscode-json-languageservice/blob/2ea5ad3d2ffbbe40dea11cfe764a502becf113ce/src/services/jsonHover.ts#L112
|
||||
toMarkdown(plain) {
|
||||
if (plain) {
|
||||
let escaped = plain.replace(/([^\n\r])(\r?\n)([^\n\r])/gm, '$1\n\n$3'); // single new lines to \n\n (Markdown paragraph)
|
||||
escaped = escaped.replace(/[\\`*_{}[\]#+\-!]/g, '\\$&'); // escape some of the markdown syntax tokens http://daringfireball.net/projects/markdown/syntax#backslash to avoid unintended formatting
|
||||
if (this.indentation !== undefined) {
|
||||
// escape indentation whitespace to prevent it from being converted to markdown code blocks.
|
||||
const indentationMatchRegex = new RegExp(` {${this.indentation.length}}`, 'g');
|
||||
escaped = escaped.replace(indentationMatchRegex, ' ');
|
||||
}
|
||||
return escaped;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
function ensureLineBreak(content) {
|
||||
if (content.length === 0) {
|
||||
return content;
|
||||
}
|
||||
if (!content.endsWith('\n')) {
|
||||
content += '\n';
|
||||
}
|
||||
return content + '\n';
|
||||
}
|
||||
function getSchemaName(schema) {
|
||||
let result = 'JSON Schema';
|
||||
const urlString = schema.url;
|
||||
if (urlString) {
|
||||
const url = URI.parse(urlString);
|
||||
result = path.basename(url.fsPath);
|
||||
}
|
||||
else if (schema.title) {
|
||||
result = schema.title;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// copied from https://github.com/microsoft/vscode-json-languageservice/blob/2ea5ad3d2ffbbe40dea11cfe764a502becf113ce/src/services/jsonHover.ts#L122
|
||||
function toMarkdownCodeBlock(content) {
|
||||
// see https://daringfireball.net/projects/markdown/syntax#precode
|
||||
if (content.indexOf('`') !== -1) {
|
||||
return '`` ' + content + ' ``';
|
||||
}
|
||||
return content;
|
||||
}
|
||||
/**
|
||||
* check all the schemas which is inside anyOf presented or not in matching schema.
|
||||
* @param node node
|
||||
* @param matchingSchemas all matching schema
|
||||
* @param schema scheam which is having anyOf
|
||||
* @returns true if all the schemas which inside anyOf presents in matching schema
|
||||
*/
|
||||
function isAllSchemasMatched(node, matchingSchemas, schema) {
|
||||
let count = 0;
|
||||
for (const matchSchema of matchingSchemas) {
|
||||
if (node === matchSchema.node && matchSchema.schema !== schema) {
|
||||
schema.anyOf.forEach((childSchema) => {
|
||||
if (matchSchema.schema.title === childSchema.title &&
|
||||
matchSchema.schema.description === childSchema.description &&
|
||||
matchSchema.schema.properties === childSchema.properties) {
|
||||
count++;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return count === schema.anyOf.length;
|
||||
}
|
||||
//# sourceMappingURL=yamlHover.js.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
import { DocumentLink } from 'vscode-languageserver-types';
|
||||
import { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
import { Telemetry } from '../telemetry';
|
||||
export declare class YamlLinks {
|
||||
private readonly telemetry?;
|
||||
constructor(telemetry?: Telemetry);
|
||||
findLinks(document: TextDocument): Promise<DocumentLink[]>;
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Red Hat, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { findLinks as JSONFindLinks } from 'vscode-json-languageservice/lib/umd/services/jsonLinks';
|
||||
import { yamlDocumentsCache } from '../parser/yaml-documents';
|
||||
export class YamlLinks {
|
||||
constructor(telemetry) {
|
||||
this.telemetry = telemetry;
|
||||
}
|
||||
findLinks(document) {
|
||||
try {
|
||||
const doc = yamlDocumentsCache.getYamlDocument(document);
|
||||
// Find links across all YAML Documents then report them back once finished
|
||||
const linkPromises = [];
|
||||
for (const yamlDoc of doc.documents) {
|
||||
linkPromises.push(JSONFindLinks(document, yamlDoc));
|
||||
}
|
||||
// Wait for all the promises to return and then flatten them into one DocumentLink array
|
||||
return Promise.all(linkPromises).then((yamlLinkArray) => [].concat(...yamlLinkArray));
|
||||
}
|
||||
catch (err) {
|
||||
this.telemetry?.sendError('yaml.documentLink.error', err);
|
||||
}
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=yamlLinks.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"yamlLinks.js","sourceRoot":"","sources":["../../../../src/languageservice/services/yamlLinks.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAChG,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,wDAAwD,CAAC;AAIpG,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,MAAM,OAAO,SAAS;IACpB,YAA6B,SAAqB;QAArB,cAAS,GAAT,SAAS,CAAY;IAAG,CAAC;IAEtD,SAAS,CAAC,QAAsB;QAC9B,IAAI;YACF,MAAM,GAAG,GAAG,kBAAkB,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YACzD,2EAA2E;YAC3E,MAAM,YAAY,GAAG,EAAE,CAAC;YACxB,KAAK,MAAM,OAAO,IAAI,GAAG,CAAC,SAAS,EAAE;gBACnC,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;aACrD;YACD,wFAAwF;YACxF,OAAO,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC;SACvF;QAAC,OAAO,GAAG,EAAE;YACZ,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;SAC3D;IACH,CAAC;CACF"}
|
||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
import { DocumentOnTypeFormattingParams } from 'vscode-languageserver';
|
||||
import { TextEdit } from 'vscode-languageserver-types';
|
||||
import { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
export declare function doDocumentOnTypeFormatting(document: TextDocument, params: DocumentOnTypeFormattingParams): TextEdit[] | undefined;
|
||||
Generated
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Red Hat, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { Position, Range, TextEdit } from 'vscode-languageserver-types';
|
||||
import { TextBuffer } from '../utils/textBuffer';
|
||||
export function doDocumentOnTypeFormatting(document, params) {
|
||||
const { position } = params;
|
||||
const tb = new TextBuffer(document);
|
||||
if (params.ch === '\n') {
|
||||
const previousLine = tb.getLineContent(position.line - 1);
|
||||
if (previousLine.trimRight().endsWith(':')) {
|
||||
const currentLine = tb.getLineContent(position.line);
|
||||
const subLine = currentLine.substring(position.character, currentLine.length);
|
||||
const isInArray = previousLine.indexOf(' - ') !== -1;
|
||||
if (subLine.trimRight().length === 0) {
|
||||
const indentationFix = position.character - (previousLine.length - previousLine.trimLeft().length);
|
||||
if (indentationFix === params.options.tabSize && !isInArray) {
|
||||
return; // skip if line already has proper formatting
|
||||
}
|
||||
const result = [];
|
||||
if (currentLine.length > 0) {
|
||||
result.push(TextEdit.del(Range.create(position, Position.create(position.line, currentLine.length - 1))));
|
||||
}
|
||||
result.push(TextEdit.insert(position, ' '.repeat(params.options.tabSize + (isInArray ? 2 - indentationFix : 0))));
|
||||
return result;
|
||||
}
|
||||
if (isInArray) {
|
||||
return [TextEdit.insert(position, ' '.repeat(params.options.tabSize))];
|
||||
}
|
||||
}
|
||||
if (previousLine.trimRight().endsWith('|')) {
|
||||
return [TextEdit.insert(position, ' '.repeat(params.options.tabSize))];
|
||||
}
|
||||
if (previousLine.includes(' - ') && !previousLine.includes(': ')) {
|
||||
return [TextEdit.insert(position, '- ')];
|
||||
}
|
||||
if (previousLine.includes(' - ') && previousLine.includes(': ')) {
|
||||
return [TextEdit.insert(position, ' ')];
|
||||
}
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=yamlOnTypeFormatting.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"yamlOnTypeFormatting.js","sourceRoot":"","sources":["../../../../src/languageservice/services/yamlOnTypeFormatting.ts"],"names":[],"mappings":"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"}
|
||||
Generated
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
import { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
import { Range, WorkspaceEdit } from 'vscode-languageserver-types';
|
||||
import { Telemetry } from '../telemetry';
|
||||
import { PrepareRenameParams, RenameParams } from 'vscode-languageserver-protocol';
|
||||
export declare class YamlRename {
|
||||
private readonly telemetry?;
|
||||
constructor(telemetry?: Telemetry);
|
||||
prepareRename(document: TextDocument, params: PrepareRenameParams): Range | null;
|
||||
doRename(document: TextDocument, params: RenameParams): WorkspaceEdit | null;
|
||||
private findTarget;
|
||||
private findByToken;
|
||||
private findAnchorToken;
|
||||
private getAnchorFromToken;
|
||||
private getAnchorFromCollectionItem;
|
||||
private getNameRange;
|
||||
private isOffsetInsideToken;
|
||||
private findInvalidAnchorChar;
|
||||
}
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Red Hat, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { Range, TextEdit } from 'vscode-languageserver-types';
|
||||
import { yamlDocumentsCache } from '../parser/yaml-documents';
|
||||
import { matchOffsetToDocument } from '../utils/arrUtils';
|
||||
import { TextBuffer } from '../utils/textBuffer';
|
||||
import { CST, isAlias, isCollection, isScalar, visit } from 'yaml';
|
||||
import { isCollectionItem } from '../utils/yamlAstUtils';
|
||||
import { ResponseError, ErrorCodes } from 'vscode-languageserver-protocol';
|
||||
export class YamlRename {
|
||||
constructor(telemetry) {
|
||||
this.telemetry = telemetry;
|
||||
}
|
||||
prepareRename(document, params) {
|
||||
try {
|
||||
const target = this.findTarget(document, params.position);
|
||||
if (!target) {
|
||||
return null;
|
||||
}
|
||||
if (!this.findAnchorToken(target.yamlDoc, target.anchorNode)) {
|
||||
return null;
|
||||
}
|
||||
return this.getNameRange(document, target.token);
|
||||
}
|
||||
catch (err) {
|
||||
this.telemetry?.sendError('yaml.prepareRename.error', err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
doRename(document, params) {
|
||||
try {
|
||||
const target = this.findTarget(document, params.position);
|
||||
if (!target) {
|
||||
return null;
|
||||
}
|
||||
const anchorToken = this.findAnchorToken(target.yamlDoc, target.anchorNode);
|
||||
if (!anchorToken) {
|
||||
return null;
|
||||
}
|
||||
const newName = params.newName;
|
||||
const invalidChar = this.findInvalidAnchorChar(newName);
|
||||
if (invalidChar !== null) {
|
||||
throw new ResponseError(ErrorCodes.InvalidParams, `Anchor name cannot contain '${invalidChar}'`);
|
||||
}
|
||||
const edits = [];
|
||||
edits.push(TextEdit.replace(this.getNameRange(document, anchorToken), newName));
|
||||
visit(target.yamlDoc.internalDocument, (key, node) => {
|
||||
if (isAlias(node) && node.srcToken && node.resolve(target.yamlDoc.internalDocument) === target.anchorNode) {
|
||||
edits.push(TextEdit.replace(this.getNameRange(document, node.srcToken), newName));
|
||||
}
|
||||
});
|
||||
return {
|
||||
changes: {
|
||||
[document.uri]: edits,
|
||||
},
|
||||
};
|
||||
}
|
||||
catch (err) {
|
||||
if (err instanceof ResponseError) {
|
||||
throw err;
|
||||
}
|
||||
this.telemetry?.sendError('yaml.rename.error', err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
findTarget(document, position) {
|
||||
const yamlDocuments = yamlDocumentsCache.getYamlDocument(document);
|
||||
const offset = document.offsetAt(position);
|
||||
const yamlDoc = matchOffsetToDocument(offset, yamlDocuments);
|
||||
if (!yamlDoc) {
|
||||
return null;
|
||||
}
|
||||
const [node] = yamlDoc.getNodeFromPosition(offset, new TextBuffer(document));
|
||||
if (!node) {
|
||||
return this.findByToken(yamlDoc, offset);
|
||||
}
|
||||
if (isAlias(node) && node.srcToken && this.isOffsetInsideToken(node.srcToken, offset)) {
|
||||
const anchorNode = node.resolve(yamlDoc.internalDocument);
|
||||
if (!anchorNode) {
|
||||
return null;
|
||||
}
|
||||
return { anchorNode, token: node.srcToken, yamlDoc };
|
||||
}
|
||||
if ((isCollection(node) || isScalar(node)) && node.anchor) {
|
||||
const anchorToken = this.findAnchorToken(yamlDoc, node);
|
||||
if (anchorToken && this.isOffsetInsideToken(anchorToken, offset)) {
|
||||
return { anchorNode: node, token: anchorToken, yamlDoc };
|
||||
}
|
||||
}
|
||||
return this.findByToken(yamlDoc, offset);
|
||||
}
|
||||
findByToken(yamlDoc, offset) {
|
||||
let target;
|
||||
visit(yamlDoc.internalDocument, (key, node) => {
|
||||
if (isAlias(node) && node.srcToken && this.isOffsetInsideToken(node.srcToken, offset)) {
|
||||
const anchorNode = node.resolve(yamlDoc.internalDocument);
|
||||
if (anchorNode) {
|
||||
target = { anchorNode, token: node.srcToken, yamlDoc };
|
||||
return visit.BREAK;
|
||||
}
|
||||
}
|
||||
if ((isCollection(node) || isScalar(node)) && node.anchor) {
|
||||
const anchorToken = this.findAnchorToken(yamlDoc, node);
|
||||
if (anchorToken && this.isOffsetInsideToken(anchorToken, offset)) {
|
||||
target = { anchorNode: node, token: anchorToken, yamlDoc };
|
||||
return visit.BREAK;
|
||||
}
|
||||
}
|
||||
});
|
||||
return target ?? null;
|
||||
}
|
||||
findAnchorToken(yamlDoc, node) {
|
||||
const parent = yamlDoc.getParent(node);
|
||||
const candidates = [];
|
||||
if (parent && parent.srcToken) {
|
||||
candidates.push(parent.srcToken);
|
||||
}
|
||||
if (node.srcToken) {
|
||||
candidates.push(node.srcToken);
|
||||
}
|
||||
for (const token of candidates) {
|
||||
const anchor = this.getAnchorFromToken(token, node);
|
||||
if (anchor) {
|
||||
return anchor;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
getAnchorFromToken(token, node) {
|
||||
if (isCollectionItem(token)) {
|
||||
return this.getAnchorFromCollectionItem(token);
|
||||
}
|
||||
else if (CST.isCollection(token)) {
|
||||
const collection = token;
|
||||
for (const item of collection.items ?? []) {
|
||||
if (item.value !== node.srcToken) {
|
||||
continue;
|
||||
}
|
||||
const anchor = this.getAnchorFromCollectionItem(item);
|
||||
if (anchor) {
|
||||
return anchor;
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
getAnchorFromCollectionItem(token) {
|
||||
for (const t of token.start) {
|
||||
if (t.type === 'anchor') {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
if (token.sep && Array.isArray(token.sep)) {
|
||||
for (const t of token.sep) {
|
||||
if (t.type === 'anchor') {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
getNameRange(document, token) {
|
||||
const startOffset = token.offset + 1;
|
||||
const endOffset = token.offset + token.source.length;
|
||||
return Range.create(document.positionAt(startOffset), document.positionAt(endOffset));
|
||||
}
|
||||
isOffsetInsideToken(token, offset) {
|
||||
return offset >= token.offset && offset <= token.offset + token.source.length;
|
||||
}
|
||||
findInvalidAnchorChar(name) {
|
||||
// YAML 1.2.2 spec: anchor names cannot contain flow indicators or whitespace
|
||||
// https://yaml.org/spec/1.2.2/#rule-ns-anchor-char
|
||||
const invalidChars = ['[', ']', '{', '}', ',', ' ', '\t'];
|
||||
for (const char of invalidChars) {
|
||||
if (name.includes(char)) {
|
||||
return char === ' ' ? 'space' : char === '\t' ? 'tab' : char;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=yamlRename.js.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+99
@@ -0,0 +1,99 @@
|
||||
import { JSONSchema } from '../jsonSchema';
|
||||
import { SchemaPriority, SchemaRequestService, WorkspaceContextService } from '../yamlLanguageService';
|
||||
import { SettingsState } from '../../yamlSettings';
|
||||
import { UnresolvedSchema, ResolvedSchema, JSONSchemaService, SchemaDependencies, ISchemaContributions, SchemaHandle } from 'vscode-json-languageservice/lib/umd/services/jsonSchemaService';
|
||||
import { JSONDocument } from '../parser/jsonDocument';
|
||||
import { JSONSchemaDescriptionExt } from '../../requestTypes';
|
||||
import { SchemaVersions } from '../yamlTypes';
|
||||
export declare type CustomSchemaProvider = (uri: string) => Promise<string | string[]>;
|
||||
export declare enum MODIFICATION_ACTIONS {
|
||||
'delete' = 0,
|
||||
'add' = 1,
|
||||
'deleteAll' = 2
|
||||
}
|
||||
export interface SchemaAdditions {
|
||||
schema: string;
|
||||
action: MODIFICATION_ACTIONS.add;
|
||||
path: string;
|
||||
key: string;
|
||||
content: any;
|
||||
}
|
||||
export interface SchemaDeletions {
|
||||
schema: string;
|
||||
action: MODIFICATION_ACTIONS.delete;
|
||||
path: string;
|
||||
key: string;
|
||||
}
|
||||
export interface SchemaDeletionsAll {
|
||||
schemas: string[];
|
||||
action: MODIFICATION_ACTIONS.deleteAll;
|
||||
}
|
||||
export declare class YAMLSchemaService extends JSONSchemaService {
|
||||
[x: string]: any;
|
||||
private customSchemaProvider;
|
||||
private filePatternAssociations;
|
||||
private contextService;
|
||||
private requestService;
|
||||
private yamlSettings;
|
||||
schemaPriorityMapping: Map<string, Set<SchemaPriority>>;
|
||||
private schemaUriToNameAndDescription;
|
||||
constructor(requestService: SchemaRequestService, contextService?: WorkspaceContextService, promiseConstructor?: PromiseConstructor, yamlSettings?: SettingsState);
|
||||
registerCustomSchemaProvider(customSchemaProvider: CustomSchemaProvider): void;
|
||||
getAllSchemas(): JSONSchemaDescriptionExt[];
|
||||
private collectSchemaNodes;
|
||||
private schemaMapValues;
|
||||
resolveSchemaContent(schemaToResolve: UnresolvedSchema, schemaURL: string, dependencies: SchemaDependencies): Promise<ResolvedSchema>;
|
||||
getSchemaForResource(resource: string, doc: JSONDocument): Promise<ResolvedSchema>;
|
||||
private finalizeResolvedSchema;
|
||||
addSchemaPriority(uri: string, priority: number): void;
|
||||
/**
|
||||
* Search through all the schemas and find the ones with the highest priority
|
||||
*/
|
||||
private highestPrioritySchemas;
|
||||
private resolveCustomSchema;
|
||||
/**
|
||||
* Save a schema with schema ID and schema content.
|
||||
* Overrides previous schemas set for that schema ID.
|
||||
*/
|
||||
saveSchema(schemaId: string, schemaContent: JSONSchema): Promise<void>;
|
||||
/**
|
||||
* Delete schemas on specific path
|
||||
*/
|
||||
deleteSchemas(deletions: SchemaDeletionsAll): Promise<void>;
|
||||
/**
|
||||
* Delete a schema with schema ID.
|
||||
*/
|
||||
deleteSchema(schemaId: string): Promise<void>;
|
||||
/**
|
||||
* Add content to a specified schema at a specified path
|
||||
*/
|
||||
addContent(additions: SchemaAdditions): Promise<void>;
|
||||
/**
|
||||
* Delete content in a specified schema at a specified path
|
||||
*/
|
||||
deleteContent(deletions: SchemaDeletions): Promise<void>;
|
||||
/**
|
||||
* Take a JSON Schema and the path that you would like to get to
|
||||
* @returns the JSON Schema resolved at that specific path
|
||||
*/
|
||||
private resolveJSONSchemaToSection;
|
||||
/**
|
||||
* Resolve the next Object if they have compatible types
|
||||
* @param object a location in the JSON Schema
|
||||
* @param token the next token that you want to search for
|
||||
*/
|
||||
private resolveNext;
|
||||
/**
|
||||
* Everything below here is needed because we're importing from vscode-json-languageservice umd and we need
|
||||
* to provide a wrapper around the javascript methods we are calling since they have no type
|
||||
*/
|
||||
normalizeId(id: string): string;
|
||||
getOrAddSchemaHandle(id: string, unresolvedSchemaContent?: JSONSchema): SchemaHandle;
|
||||
loadSchema(schemaUri: string): Promise<UnresolvedSchema>;
|
||||
registerExternalSchema(uri: string, filePatterns?: string[], unresolvedSchema?: JSONSchema, name?: string, description?: string, versions?: SchemaVersions): SchemaHandle;
|
||||
clearExternalSchemas(): void;
|
||||
setSchemaContributions(schemaContributions: ISchemaContributions): void;
|
||||
getRegisteredSchemaIds(filter?: (scheme: any) => boolean): string[];
|
||||
getResolvedSchema(schemaId: string): Promise<ResolvedSchema>;
|
||||
onResourceChange(uri: string): boolean;
|
||||
}
|
||||
Generated
Vendored
+1025
File diff suppressed because it is too large
Load Diff
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
import { Position, SelectionRange } from 'vscode-languageserver-types';
|
||||
import { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
export declare function getSelectionRanges(document: TextDocument, positions: Position[]): SelectionRange[];
|
||||
Generated
Vendored
+130
@@ -0,0 +1,130 @@
|
||||
import { SelectionRange } from 'vscode-languageserver-types';
|
||||
import { yamlDocumentsCache } from '../parser/yaml-documents';
|
||||
export function getSelectionRanges(document, positions) {
|
||||
const doc = yamlDocumentsCache.getYamlDocument(document);
|
||||
return positions.map((position) => {
|
||||
const ranges = getRanges(position);
|
||||
let current;
|
||||
for (const range of ranges) {
|
||||
current = SelectionRange.create(range, current);
|
||||
}
|
||||
return current ?? SelectionRange.create({ start: position, end: position });
|
||||
});
|
||||
function getRanges(position) {
|
||||
const offset = document.offsetAt(position);
|
||||
const result = [];
|
||||
for (const ymlDoc of doc.documents) {
|
||||
let currentNode;
|
||||
let overrideStartOffset;
|
||||
ymlDoc.visit((node) => {
|
||||
const endOffset = node.offset + node.length;
|
||||
// Skip if end offset doesn't even reach cursor position
|
||||
if (endOffset < offset) {
|
||||
return true;
|
||||
}
|
||||
// Skip if we're ending at new line
|
||||
// times:
|
||||
// - second: 1
|
||||
// millisecond: 10
|
||||
// | - second: 2
|
||||
// ↑ millisecond: 0
|
||||
// (| is actually part of { second: 1, millisecond: 10 })
|
||||
// \r\n doesn't matter here
|
||||
if (getTextFromOffsets(endOffset - 1, endOffset) === '\n') {
|
||||
if (endOffset - 1 < offset) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
let startOffset = node.offset;
|
||||
if (startOffset > offset) {
|
||||
// Recheck start offset for some special cases
|
||||
const newOffset = getStartOffsetForSpecialCases(node, position);
|
||||
if (!newOffset || newOffset > offset) {
|
||||
return true;
|
||||
}
|
||||
startOffset = newOffset;
|
||||
}
|
||||
// Allow equal for children to override
|
||||
if (!currentNode || startOffset >= currentNode.offset) {
|
||||
currentNode = node;
|
||||
overrideStartOffset = startOffset;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
while (currentNode) {
|
||||
const startOffset = overrideStartOffset ?? currentNode.offset;
|
||||
const endOffset = currentNode.offset + currentNode.length;
|
||||
const range = {
|
||||
start: document.positionAt(startOffset),
|
||||
end: document.positionAt(endOffset),
|
||||
};
|
||||
const text = document.getText(range);
|
||||
const trimmedText = trimEndNewLine(text);
|
||||
const trimmedEndOffset = startOffset + trimmedText.length;
|
||||
if (trimmedEndOffset >= offset) {
|
||||
range.end = document.positionAt(trimmedEndOffset);
|
||||
}
|
||||
// Add a jump between '' "" {} []
|
||||
const isSurroundedBy = (startCharacter, endCharacter) => {
|
||||
return trimmedText.startsWith(startCharacter) && trimmedText.endsWith(endCharacter || startCharacter);
|
||||
};
|
||||
if ((currentNode.type === 'string' && (isSurroundedBy("'") || isSurroundedBy('"'))) ||
|
||||
(currentNode.type === 'object' && isSurroundedBy('{', '}')) ||
|
||||
(currentNode.type === 'array' && isSurroundedBy('[', ']'))) {
|
||||
result.push({
|
||||
start: document.positionAt(startOffset + 1),
|
||||
end: document.positionAt(endOffset - 1),
|
||||
});
|
||||
}
|
||||
result.push(range);
|
||||
currentNode = currentNode.parent;
|
||||
overrideStartOffset = undefined;
|
||||
}
|
||||
// A position can't be in multiple documents
|
||||
if (result.length > 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result.reverse();
|
||||
}
|
||||
function getStartOffsetForSpecialCases(node, position) {
|
||||
const nodeStartPosition = document.positionAt(node.offset);
|
||||
if (nodeStartPosition.line !== position.line) {
|
||||
return;
|
||||
}
|
||||
if (node.parent?.type === 'array') {
|
||||
// array:
|
||||
// - value
|
||||
// ↑
|
||||
if (getTextFromOffsets(node.offset - 2, node.offset) === '- ') {
|
||||
return node.offset - 2;
|
||||
}
|
||||
}
|
||||
if (node.type === 'array' || node.type === 'object') {
|
||||
// array:
|
||||
// - value
|
||||
// ↑
|
||||
const lineBeginning = { line: nodeStartPosition.line, character: 0 };
|
||||
const text = document.getText({ start: lineBeginning, end: nodeStartPosition });
|
||||
if (text.trim().length === 0) {
|
||||
return document.offsetAt(lineBeginning);
|
||||
}
|
||||
}
|
||||
}
|
||||
function getTextFromOffsets(startOffset, endOffset) {
|
||||
return document.getText({
|
||||
start: document.positionAt(startOffset),
|
||||
end: document.positionAt(endOffset),
|
||||
});
|
||||
}
|
||||
}
|
||||
function trimEndNewLine(str) {
|
||||
if (str.endsWith('\r\n')) {
|
||||
return str.substring(0, str.length - 2);
|
||||
}
|
||||
if (str.endsWith('\n')) {
|
||||
return str.substring(0, str.length - 1);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
//# sourceMappingURL=yamlSelectionRanges.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"yamlSelectionRanges.js","sourceRoot":"","sources":["../../../../src/languageservice/services/yamlSelectionRanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAI9D,MAAM,UAAU,kBAAkB,CAAC,QAAsB,EAAE,SAAqB;IAC9E,MAAM,GAAG,GAAG,kBAAkB,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;IACzD,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;QAChC,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;QACnC,IAAI,OAAmC,CAAC;QACxC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;YAC1B,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;SACjD;QACD,OAAO,OAAO,IAAI,cAAc,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,SAAS,SAAS,CAAC,QAAkB;QACnC,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAY,EAAE,CAAC;QAC3B,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,SAAS,EAAE;YAClC,IAAI,WAAgC,CAAC;YACrC,IAAI,mBAAuC,CAAC;YAC5C,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE;gBACpB,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;gBAC5C,wDAAwD;gBACxD,IAAI,SAAS,GAAG,MAAM,EAAE;oBACtB,OAAO,IAAI,CAAC;iBACb;gBACD,mCAAmC;gBACnC,SAAS;gBACT,gBAAgB;gBAChB,sBAAsB;gBACtB,gBAAgB;gBAChB,qBAAqB;gBACrB,yDAAyD;gBACzD,2BAA2B;gBAC3B,IAAI,kBAAkB,CAAC,SAAS,GAAG,CAAC,EAAE,SAAS,CAAC,KAAK,IAAI,EAAE;oBACzD,IAAI,SAAS,GAAG,CAAC,GAAG,MAAM,EAAE;wBAC1B,OAAO,IAAI,CAAC;qBACb;iBACF;gBAED,IAAI,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC;gBAC9B,IAAI,WAAW,GAAG,MAAM,EAAE;oBACxB,8CAA8C;oBAC9C,MAAM,SAAS,GAAG,6BAA6B,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;oBAChE,IAAI,CAAC,SAAS,IAAI,SAAS,GAAG,MAAM,EAAE;wBACpC,OAAO,IAAI,CAAC;qBACb;oBACD,WAAW,GAAG,SAAS,CAAC;iBACzB;gBAED,uCAAuC;gBACvC,IAAI,CAAC,WAAW,IAAI,WAAW,IAAI,WAAW,CAAC,MAAM,EAAE;oBACrD,WAAW,GAAG,IAAI,CAAC;oBACnB,mBAAmB,GAAG,WAAW,CAAC;iBACnC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC,CAAC,CAAC;YACH,OAAO,WAAW,EAAE;gBAClB,MAAM,WAAW,GAAG,mBAAmB,IAAI,WAAW,CAAC,MAAM,CAAC;gBAC9D,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;gBAC1D,MAAM,KAAK,GAAG;oBACZ,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC;oBACvC,GAAG,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC;iBACpC,CAAC;gBACF,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBACrC,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;gBACzC,MAAM,gBAAgB,GAAG,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC;gBAC1D,IAAI,gBAAgB,IAAI,MAAM,EAAE;oBAC9B,KAAK,CAAC,GAAG,GAAG,QAAQ,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;iBACnD;gBACD,iCAAiC;gBACjC,MAAM,cAAc,GAAG,CAAC,cAAsB,EAAE,YAAqB,EAAW,EAAE;oBAChF,OAAO,WAAW,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,YAAY,IAAI,cAAc,CAAC,CAAC;gBACxG,CAAC,CAAC;gBACF,IACE,CAAC,WAAW,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;oBAC/E,CAAC,WAAW,CAAC,IAAI,KAAK,QAAQ,IAAI,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;oBAC3D,CAAC,WAAW,CAAC,IAAI,KAAK,OAAO,IAAI,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,EAC1D;oBACA,MAAM,CAAC,IAAI,CAAC;wBACV,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,WAAW,GAAG,CAAC,CAAC;wBAC3C,GAAG,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,GAAG,CAAC,CAAC;qBACxC,CAAC,CAAC;iBACJ;gBACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACnB,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC;gBACjC,mBAAmB,GAAG,SAAS,CAAC;aACjC;YACD,4CAA4C;YAC5C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;gBACrB,MAAM;aACP;SACF;QACD,OAAO,MAAM,CAAC,OAAO,EAAE,CAAC;IAC1B,CAAC;IAED,SAAS,6BAA6B,CAAC,IAAa,EAAE,QAAkB;QACtE,MAAM,iBAAiB,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3D,IAAI,iBAAiB,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,EAAE;YAC5C,OAAO;SACR;QAED,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,KAAK,OAAO,EAAE;YACjC,SAAS;YACT,YAAY;YACZ,OAAO;YACP,IAAI,kBAAkB,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;gBAC7D,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;aACxB;SACF;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE;YACnD,SAAS;YACT,YAAY;YACZ,IAAI;YACJ,MAAM,aAAa,GAAG,EAAE,IAAI,EAAE,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;YACrE,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,iBAAiB,EAAE,CAAC,CAAC;YAChF,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE;gBAC5B,OAAO,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;aACzC;SACF;IACH,CAAC;IAED,SAAS,kBAAkB,CAAC,WAAmB,EAAE,SAAiB;QAChE,OAAO,QAAQ,CAAC,OAAO,CAAC;YACtB,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC;YACvC,GAAG,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC;SACpC,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,GAAW;IACjC,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;QACxB,OAAO,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;KACzC;IACD,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;QACtB,OAAO,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;KACzC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
||||
Generated
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
import { Diagnostic } from 'vscode-languageserver-types';
|
||||
import { LanguageSettings } from '../yamlLanguageService';
|
||||
import { YAMLSchemaService } from './yamlSchemaService';
|
||||
import { YAMLDocDiagnostic } from '../utils/parseUtils';
|
||||
import { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
import { Telemetry } from '../telemetry';
|
||||
/**
|
||||
* Convert a YAMLDocDiagnostic to a language server Diagnostic
|
||||
* @param yamlDiag A YAMLDocDiagnostic from the parser
|
||||
* @param textDocument TextDocument from the language server client
|
||||
*/
|
||||
export declare const yamlDiagToLSDiag: (yamlDiag: YAMLDocDiagnostic, textDocument: TextDocument) => Diagnostic;
|
||||
export declare class YAMLValidation {
|
||||
private readonly telemetry?;
|
||||
private validationEnabled;
|
||||
private customTags;
|
||||
private jsonValidation;
|
||||
private disableAdditionalProperties;
|
||||
private yamlVersion;
|
||||
private validators;
|
||||
private MATCHES_MULTIPLE;
|
||||
constructor(schemaService: YAMLSchemaService, telemetry?: Telemetry);
|
||||
configure(settings: LanguageSettings): void;
|
||||
doValidation(textDocument: TextDocument, isKubernetes?: boolean): Promise<Diagnostic[]>;
|
||||
private runAdditionalValidators;
|
||||
}
|
||||
Generated
Vendored
+128
@@ -0,0 +1,128 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Red Hat, Inc. 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.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { Diagnostic, Position } from 'vscode-languageserver-types';
|
||||
import { JSONValidation } from 'vscode-json-languageservice/lib/umd/services/jsonValidation';
|
||||
import { YAML_SOURCE } from '../parser/schemaValidation/baseValidator';
|
||||
import { TextBuffer } from '../utils/textBuffer';
|
||||
import { yamlDocumentsCache } from '../parser/yaml-documents';
|
||||
import { UnusedAnchorsValidator } from './validation/unused-anchors';
|
||||
import { YAMLStyleValidator } from './validation/yaml-style';
|
||||
import { MapKeyOrderValidator } from './validation/map-key-order';
|
||||
/**
|
||||
* Convert a YAMLDocDiagnostic to a language server Diagnostic
|
||||
* @param yamlDiag A YAMLDocDiagnostic from the parser
|
||||
* @param textDocument TextDocument from the language server client
|
||||
*/
|
||||
export const yamlDiagToLSDiag = (yamlDiag, textDocument) => {
|
||||
const start = textDocument.positionAt(yamlDiag.location.start);
|
||||
const range = {
|
||||
start,
|
||||
end: yamlDiag.location.toLineEnd
|
||||
? Position.create(start.line, new TextBuffer(textDocument).getLineLength(start.line))
|
||||
: textDocument.positionAt(yamlDiag.location.end),
|
||||
};
|
||||
return Diagnostic.create(range, yamlDiag.message, yamlDiag.severity, yamlDiag.code, YAML_SOURCE);
|
||||
};
|
||||
export class YAMLValidation {
|
||||
constructor(schemaService, telemetry) {
|
||||
this.telemetry = telemetry;
|
||||
this.validators = [];
|
||||
this.MATCHES_MULTIPLE = 'Matches multiple schemas when only one must validate.';
|
||||
this.validationEnabled = true;
|
||||
this.jsonValidation = new JSONValidation(schemaService, Promise);
|
||||
}
|
||||
configure(settings) {
|
||||
this.validators = [];
|
||||
if (settings) {
|
||||
this.validationEnabled = settings.validate;
|
||||
this.customTags = settings.customTags;
|
||||
this.disableAdditionalProperties = settings.disableAdditionalProperties;
|
||||
this.yamlVersion = settings.yamlVersion;
|
||||
// Add style validator if flow style is set to forbid only.
|
||||
if (settings.flowMapping === 'forbid' || settings.flowSequence === 'forbid') {
|
||||
this.validators.push(new YAMLStyleValidator(settings));
|
||||
}
|
||||
if (settings.keyOrdering) {
|
||||
this.validators.push(new MapKeyOrderValidator());
|
||||
}
|
||||
}
|
||||
this.validators.push(new UnusedAnchorsValidator());
|
||||
}
|
||||
async doValidation(textDocument, isKubernetes = false) {
|
||||
if (!this.validationEnabled) {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
const validationResult = [];
|
||||
try {
|
||||
const yamlDocument = yamlDocumentsCache.getYamlDocument(textDocument, { customTags: this.customTags, yamlVersion: this.yamlVersion }, true);
|
||||
let index = 0;
|
||||
for (const currentYAMLDoc of yamlDocument.documents) {
|
||||
currentYAMLDoc.isKubernetes = isKubernetes;
|
||||
currentYAMLDoc.currentDocIndex = index;
|
||||
currentYAMLDoc.disableAdditionalProperties = this.disableAdditionalProperties;
|
||||
currentYAMLDoc.uri = textDocument.uri;
|
||||
const validation = await this.jsonValidation.doValidation(textDocument, currentYAMLDoc);
|
||||
const syd = currentYAMLDoc;
|
||||
if (syd.errors.length > 0) {
|
||||
// TODO: Get rid of these type assertions (shouldn't need them)
|
||||
validationResult.push(...syd.errors);
|
||||
}
|
||||
if (syd.warnings.length > 0) {
|
||||
validationResult.push(...syd.warnings);
|
||||
}
|
||||
validationResult.push(...validation);
|
||||
validationResult.push(...this.runAdditionalValidators(textDocument, currentYAMLDoc));
|
||||
index++;
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
this.telemetry?.sendError('yaml.validation.error', err);
|
||||
}
|
||||
let previousErr;
|
||||
const foundSignatures = new Set();
|
||||
const duplicateMessagesRemoved = [];
|
||||
for (let err of validationResult) {
|
||||
/**
|
||||
* A patch ontop of the validation that removes the
|
||||
* 'Matches many schemas' error for kubernetes
|
||||
* for a better user experience.
|
||||
*/
|
||||
if (isKubernetes && err.message === this.MATCHES_MULTIPLE) {
|
||||
continue;
|
||||
}
|
||||
if (Object.prototype.hasOwnProperty.call(err, 'location')) {
|
||||
err = yamlDiagToLSDiag(err, textDocument);
|
||||
}
|
||||
if (!err.source) {
|
||||
err.source = YAML_SOURCE;
|
||||
}
|
||||
if (previousErr &&
|
||||
previousErr.message === err.message &&
|
||||
previousErr.range.end.line === err.range.start.line &&
|
||||
Math.abs(previousErr.range.end.character - err.range.end.character) >= 1) {
|
||||
previousErr.range.end = err.range.end;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
previousErr = err;
|
||||
}
|
||||
const errSig = err.range.start.line + ' ' + err.range.start.character + ' ' + err.message;
|
||||
if (!foundSignatures.has(errSig)) {
|
||||
duplicateMessagesRemoved.push(err);
|
||||
foundSignatures.add(errSig);
|
||||
}
|
||||
}
|
||||
return duplicateMessagesRemoved;
|
||||
}
|
||||
runAdditionalValidators(document, yarnDoc) {
|
||||
const result = [];
|
||||
for (const validator of this.validators) {
|
||||
result.push(...validator.validate(document, yarnDoc));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=yamlValidation.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"yamlValidation.js","sourceRoot":"","sources":["../../../../src/languageservice/services/yamlValidation.ts"],"names":[],"mappings":"AAAA;;;;gGAIgG;AAEhG,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAMnE,OAAO,EAAE,cAAc,EAAE,MAAM,6DAA6D,CAAC;AAC7F,OAAO,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAG9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAElE;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,QAA2B,EAAE,YAA0B,EAAc,EAAE;IACtG,MAAM,KAAK,GAAG,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG;QACZ,KAAK;QACL,GAAG,EAAE,QAAQ,CAAC,QAAQ,CAAC,SAAS;YAC9B,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,UAAU,CAAC,YAAY,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACrF,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC;KACnD,CAAC;IAEF,OAAO,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;AACnG,CAAC,CAAC;AAEF,MAAM,OAAO,cAAc;IAUzB,YACE,aAAgC,EACf,SAAqB;QAArB,cAAS,GAAT,SAAS,CAAY;QANhC,eAAU,GAA0B,EAAE,CAAC;QAEvC,qBAAgB,GAAG,uDAAuD,CAAC;QAMjF,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,IAAI,CAAC,cAAc,GAAG,IAAI,cAAc,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACnE,CAAC;IAEM,SAAS,CAAC,QAA0B;QACzC,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QACrB,IAAI,QAAQ,EAAE;YACZ,IAAI,CAAC,iBAAiB,GAAG,QAAQ,CAAC,QAAQ,CAAC;YAC3C,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC;YACtC,IAAI,CAAC,2BAA2B,GAAG,QAAQ,CAAC,2BAA2B,CAAC;YACxE,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC;YACxC,2DAA2D;YAC3D,IAAI,QAAQ,CAAC,WAAW,KAAK,QAAQ,IAAI,QAAQ,CAAC,YAAY,KAAK,QAAQ,EAAE;gBAC3E,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC;aACxD;YACD,IAAI,QAAQ,CAAC,WAAW,EAAE;gBACxB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;aAClD;SACF;QACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,sBAAsB,EAAE,CAAC,CAAC;IACrD,CAAC;IAEM,KAAK,CAAC,YAAY,CAAC,YAA0B,EAAE,YAAY,GAAG,KAAK;QACxE,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE;YAC3B,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;SAC5B;QAED,MAAM,gBAAgB,GAAG,EAAE,CAAC;QAC5B,IAAI;YACF,MAAM,YAAY,GAAiB,kBAAkB,CAAC,eAAe,CACnE,YAAY,EACZ,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,EAC9D,IAAI,CACL,CAAC;YAEF,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,KAAK,MAAM,cAAc,IAAI,YAAY,CAAC,SAAS,EAAE;gBACnD,cAAc,CAAC,YAAY,GAAG,YAAY,CAAC;gBAC3C,cAAc,CAAC,eAAe,GAAG,KAAK,CAAC;gBACvC,cAAc,CAAC,2BAA2B,GAAG,IAAI,CAAC,2BAA2B,CAAC;gBAC9E,cAAc,CAAC,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC;gBAEtC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;gBAExF,MAAM,GAAG,GAAG,cAA+C,CAAC;gBAC5D,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;oBACzB,+DAA+D;oBAC/D,gBAAgB,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;iBACtC;gBACD,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;oBAC3B,gBAAgB,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC;iBACxC;gBAED,gBAAgB,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;gBACrC,gBAAgB,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,uBAAuB,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC,CAAC;gBACrF,KAAK,EAAE,CAAC;aACT;SACF;QAAC,OAAO,GAAG,EAAE;YACZ,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;SACzD;QAED,IAAI,WAAuB,CAAC;QAC5B,MAAM,eAAe,GAAG,IAAI,GAAG,EAAE,CAAC;QAClC,MAAM,wBAAwB,GAAiB,EAAE,CAAC;QAClD,KAAK,IAAI,GAAG,IAAI,gBAAgB,EAAE;YAChC;;;;eAIG;YACH,IAAI,YAAY,IAAI,GAAG,CAAC,OAAO,KAAK,IAAI,CAAC,gBAAgB,EAAE;gBACzD,SAAS;aACV;YAED,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE;gBACzD,GAAG,GAAG,gBAAgB,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;aAC3C;YAED,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE;gBACf,GAAG,CAAC,MAAM,GAAG,WAAW,CAAC;aAC1B;YAED,IACE,WAAW;gBACX,WAAW,CAAC,OAAO,KAAK,GAAG,CAAC,OAAO;gBACnC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI;gBACnD,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EACxE;gBACA,WAAW,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;gBACtC,SAAS;aACV;iBAAM;gBACL,WAAW,GAAG,GAAG,CAAC;aACnB;YAED,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC;YAC1F,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;gBAChC,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACnC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;aAC7B;SACF;QAED,OAAO,wBAAwB,CAAC;IAClC,CAAC;IACO,uBAAuB,CAAC,QAAsB,EAAE,OAA2B;QACjF,MAAM,MAAM,GAAG,EAAE,CAAC;QAElB,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE;YACvC,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;SACvD;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|
||||
Reference in New Issue
Block a user