-
Notifications
You must be signed in to change notification settings - Fork 264
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Show all json schemas for yaml file in codelens (#424)
* #412 Implement CodeLens, show all json schemas in codelens Signed-off-by: Yevhen Vydolob <[email protected]> * Fix review comments Signed-off-by: Yevhen Vydolob <[email protected]> * delete commented code Signed-off-by: Yevhen Vydolob <[email protected]> * Use 'isBooelan' as type gard Signed-off-by: Yevhen Vydolob <[email protected]> * fix tests Signed-off-by: Yevhen Vydolob <[email protected]>
- Loading branch information
Showing
17 changed files
with
445 additions
and
70 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/*--------------------------------------------------------------------------------------------- | ||
* Copyright (c) Red Hat, Inc. All rights reserved. | ||
* Licensed under the MIT License. See License.txt in the project root for license information. | ||
*--------------------------------------------------------------------------------------------*/ | ||
|
||
import { TextDocument } from 'vscode-languageserver-textdocument'; | ||
import { YAMLDocument, parse as parseYAML } from './yamlParser07'; | ||
|
||
interface YamlCachedDocument { | ||
version: number; | ||
document: YAMLDocument; | ||
} | ||
export class YamlDocuments { | ||
// a mapping of URIs to cached documents | ||
private cache = new Map<string, YamlCachedDocument>(); | ||
|
||
/** | ||
* Get cached YAMLDocument | ||
* @param document TextDocument to parse | ||
* @param customTags YAML custom tags | ||
* @param addRootObject if true and document is empty add empty object {} to force schema usage | ||
* @returns the YAMLDocument | ||
*/ | ||
getYamlDocument(document: TextDocument, customTags: string[] = [], addRootObject = false): YAMLDocument { | ||
this.ensureCache(document, customTags, addRootObject); | ||
return this.cache.get(document.uri).document; | ||
} | ||
|
||
/** | ||
* For test purpose only! | ||
*/ | ||
clear(): void { | ||
this.cache.clear(); | ||
} | ||
|
||
private ensureCache(document: TextDocument, customTags: string[], addRootObject: boolean): void { | ||
const key = document.uri; | ||
if (!this.cache.has(key)) { | ||
this.cache.set(key, { version: -1, document: new YAMLDocument([]) }); | ||
} | ||
|
||
if (this.cache.get(key).version !== document.version) { | ||
let text = document.getText(); | ||
// if text is contains only whitespace wrap all text in object to force schema selection | ||
if (addRootObject && !/\S/.test(text)) { | ||
text = `{${text}}`; | ||
} | ||
const doc = parseYAML(text, customTags); | ||
this.cache.get(key).document = doc; | ||
this.cache.get(key).version = document.version; | ||
} | ||
} | ||
} | ||
|
||
export const yamlDocumentsCache = new YamlDocuments(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/*--------------------------------------------------------------------------------------------- | ||
* Copyright (c) Red Hat, Inc. All rights reserved. | ||
* Licensed under the MIT License. See License.txt in the project root for license information. | ||
*--------------------------------------------------------------------------------------------*/ | ||
|
||
import { TextDocument } from 'vscode-languageserver-textdocument'; | ||
import { CodeLens, Range } from 'vscode-languageserver-types'; | ||
import { YamlCommands } from '../../commands'; | ||
import { yamlDocumentsCache } from '../parser/yaml-documents'; | ||
import { YAMLSchemaService } from './yamlSchemaService'; | ||
import { URI } from 'vscode-uri'; | ||
import * as path from 'path'; | ||
import { JSONSchema, JSONSchemaRef } from '../jsonSchema'; | ||
import { CodeLensParams } from 'vscode-languageserver-protocol'; | ||
import { isBoolean } from '../utils/objects'; | ||
|
||
export class YamlCodeLens { | ||
constructor(private schemaService: YAMLSchemaService) {} | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
async getCodeLens(document: TextDocument, params: CodeLensParams): Promise<CodeLens[]> { | ||
const yamlDocument = yamlDocumentsCache.getYamlDocument(document); | ||
const result = []; | ||
for (const currentYAMLDoc of yamlDocument.documents) { | ||
const schema = await this.schemaService.getSchemaForResource(document.uri, currentYAMLDoc); | ||
if (schema?.schema) { | ||
const schemaUrls = getSchemaUrl(schema?.schema); | ||
if (schemaUrls.size === 0) { | ||
continue; | ||
} | ||
for (const urlToSchema of schemaUrls) { | ||
const lens = CodeLens.create(Range.create(0, 0, 0, 0)); | ||
lens.command = { | ||
title: getCommandTitle(urlToSchema[0], urlToSchema[1]), | ||
command: YamlCommands.JUMP_TO_SCHEMA, | ||
arguments: [urlToSchema[0]], | ||
}; | ||
result.push(lens); | ||
} | ||
} | ||
} | ||
|
||
return result; | ||
} | ||
resolveCodeLens(param: CodeLens): Thenable<CodeLens> | CodeLens { | ||
return param; | ||
} | ||
} | ||
|
||
function getCommandTitle(url: string, schema: JSONSchema): string { | ||
const uri = URI.parse(url); | ||
let baseName = path.basename(uri.fsPath); | ||
if (!path.extname(uri.fsPath)) { | ||
baseName += '.json'; | ||
} | ||
if (Object.getOwnPropertyDescriptor(schema, 'name')) { | ||
return Object.getOwnPropertyDescriptor(schema, 'name').value + ` (${baseName})`; | ||
} else if (schema.title) { | ||
return schema.title + ` (${baseName})`; | ||
} | ||
|
||
return baseName; | ||
} | ||
|
||
function getSchemaUrl(schema: JSONSchema): Map<string, JSONSchema> { | ||
const result = new Map<string, JSONSchema>(); | ||
if (!schema) { | ||
return result; | ||
} | ||
const url = schema.url; | ||
if (url) { | ||
if (url.startsWith('schemaservice://combinedSchema/')) { | ||
addSchemasForOf(schema, result); | ||
} else { | ||
result.set(schema.url, schema); | ||
} | ||
} else { | ||
addSchemasForOf(schema, result); | ||
} | ||
return result; | ||
} | ||
|
||
function addSchemasForOf(schema: JSONSchema, result: Map<string, JSONSchema>): void { | ||
if (schema.allOf) { | ||
addInnerSchemaUrls(schema.allOf, result); | ||
} | ||
if (schema.anyOf) { | ||
addInnerSchemaUrls(schema.anyOf, result); | ||
} | ||
if (schema.oneOf) { | ||
addInnerSchemaUrls(schema.oneOf, result); | ||
} | ||
} | ||
|
||
function addInnerSchemaUrls(schemas: JSONSchemaRef[], result: Map<string, JSONSchema>): void { | ||
for (const subSchema of schemas) { | ||
if (!isBoolean(subSchema)) { | ||
if (subSchema.url && !result.has(subSchema.url)) { | ||
result.set(subSchema.url, subSchema); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 { Connection } from 'vscode-languageserver/node'; | ||
import { YamlCommands } from '../../commands'; | ||
import { CommandExecutor } from '../../languageserver/commandExecutor'; | ||
import { URI } from 'vscode-uri'; | ||
|
||
export function registerCommands(commandExecutor: CommandExecutor, connection: Connection): void { | ||
commandExecutor.registerCommand(YamlCommands.JUMP_TO_SCHEMA, async (uri: string) => { | ||
if (!uri) { | ||
return; | ||
} | ||
if (!uri.startsWith('file')) { | ||
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(); | ||
} | ||
|
||
const result = await connection.window.showDocument({ uri: uri, external: false, takeFocus: true }); | ||
if (!result) { | ||
connection.window.showErrorMessage(`Cannot open ${uri}`); | ||
} | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.