add getLanguageStatus
This commit is contained in:
Родитель
338d55069a
Коммит
e87ed1afb4
|
@ -1,4 +1,9 @@
|
||||||
|
|
||||||
|
|
||||||
|
4.2.0 /
|
||||||
|
================
|
||||||
|
* new API `LanguageService.getLanguageStatus`
|
||||||
|
|
||||||
4.1.6 / 2021-07-16
|
4.1.6 / 2021-07-16
|
||||||
================
|
================
|
||||||
* Replace minimatch with glob-to-regexp
|
* Replace minimatch with glob-to-regexp
|
||||||
|
|
|
@ -23,7 +23,7 @@ import {
|
||||||
FoldingRange, JSONSchema, SelectionRange, FoldingRangesContext, DocumentSymbolsContext, ColorInformationContext as DocumentColorsContext,
|
FoldingRange, JSONSchema, SelectionRange, FoldingRangesContext, DocumentSymbolsContext, ColorInformationContext as DocumentColorsContext,
|
||||||
TextDocument,
|
TextDocument,
|
||||||
Position, CompletionItem, CompletionList, Hover, Range, SymbolInformation, Diagnostic,
|
Position, CompletionItem, CompletionList, Hover, Range, SymbolInformation, Diagnostic,
|
||||||
TextEdit, FormattingOptions, DocumentSymbol, DefinitionLink, MatchingSchema
|
TextEdit, FormattingOptions, DocumentSymbol, DefinitionLink, MatchingSchema, JSONLanguageStatus
|
||||||
} from './jsonLanguageTypes';
|
} from './jsonLanguageTypes';
|
||||||
import { findLinks } from './services/jsonLinks';
|
import { findLinks } from './services/jsonLinks';
|
||||||
import { DocumentLink } from 'vscode-languageserver-types';
|
import { DocumentLink } from 'vscode-languageserver-types';
|
||||||
|
@ -41,6 +41,7 @@ export interface LanguageService {
|
||||||
newJSONDocument(rootNode: ASTNode, syntaxDiagnostics?: Diagnostic[]): JSONDocument;
|
newJSONDocument(rootNode: ASTNode, syntaxDiagnostics?: Diagnostic[]): JSONDocument;
|
||||||
resetSchema(uri: string): boolean;
|
resetSchema(uri: string): boolean;
|
||||||
getMatchingSchemas(document: TextDocument, jsonDocument: JSONDocument, schema?: JSONSchema): Thenable<MatchingSchema[]>;
|
getMatchingSchemas(document: TextDocument, jsonDocument: JSONDocument, schema?: JSONSchema): Thenable<MatchingSchema[]>;
|
||||||
|
getLanguageStatus(document: TextDocument, jsonDocument: JSONDocument): JSONLanguageStatus;
|
||||||
doResolve(item: CompletionItem): Thenable<CompletionItem>;
|
doResolve(item: CompletionItem): Thenable<CompletionItem>;
|
||||||
doComplete(document: TextDocument, position: Position, doc: JSONDocument): Thenable<CompletionList | null>;
|
doComplete(document: TextDocument, position: Position, doc: JSONDocument): Thenable<CompletionList | null>;
|
||||||
findDocumentSymbols(document: TextDocument, doc: JSONDocument, context?: DocumentSymbolsContext): SymbolInformation[];
|
findDocumentSymbols(document: TextDocument, doc: JSONDocument, context?: DocumentSymbolsContext): SymbolInformation[];
|
||||||
|
@ -79,6 +80,7 @@ export function getLanguageService(params: LanguageServiceParams): LanguageServi
|
||||||
},
|
},
|
||||||
resetSchema: (uri: string) => jsonSchemaService.onResourceChange(uri),
|
resetSchema: (uri: string) => jsonSchemaService.onResourceChange(uri),
|
||||||
doValidation: jsonValidation.doValidation.bind(jsonValidation),
|
doValidation: jsonValidation.doValidation.bind(jsonValidation),
|
||||||
|
getLanguageStatus: jsonValidation.getLanguageStatus.bind(jsonValidation),
|
||||||
parseJSONDocument: (document: TextDocument) => parseJSON(document, { collectComments: true }),
|
parseJSONDocument: (document: TextDocument) => parseJSON(document, { collectComments: true }),
|
||||||
newJSONDocument: (root: ASTNode, diagnostics: Diagnostic[]) => newJSONDocument(root, diagnostics),
|
newJSONDocument: (root: ASTNode, diagnostics: Diagnostic[]) => newJSONDocument(root, diagnostics),
|
||||||
getMatchingSchemas: jsonSchemaService.getMatchingSchemas.bind(jsonSchemaService),
|
getMatchingSchemas: jsonSchemaService.getMatchingSchemas.bind(jsonSchemaService),
|
||||||
|
|
|
@ -15,7 +15,7 @@ import {
|
||||||
SymbolInformation, SymbolKind, DocumentSymbol, Location, Hover, MarkedString, FormattingOptions as LSPFormattingOptions, DefinitionLink,
|
SymbolInformation, SymbolKind, DocumentSymbol, Location, Hover, MarkedString, FormattingOptions as LSPFormattingOptions, DefinitionLink,
|
||||||
CodeActionContext, Command, CodeAction,
|
CodeActionContext, Command, CodeAction,
|
||||||
DocumentHighlight, DocumentLink, WorkspaceEdit,
|
DocumentHighlight, DocumentLink, WorkspaceEdit,
|
||||||
TextEdit, CodeActionKind,
|
TextEdit, CodeActionKind,
|
||||||
TextDocumentEdit, VersionedTextDocumentIdentifier, DocumentHighlightKind
|
TextDocumentEdit, VersionedTextDocumentIdentifier, DocumentHighlightKind
|
||||||
} from 'vscode-languageserver-types';
|
} from 'vscode-languageserver-types';
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ export {
|
||||||
SymbolInformation, SymbolKind, DocumentSymbol, Location, Hover, MarkedString,
|
SymbolInformation, SymbolKind, DocumentSymbol, Location, Hover, MarkedString,
|
||||||
CodeActionContext, Command, CodeAction,
|
CodeActionContext, Command, CodeAction,
|
||||||
DocumentHighlight, DocumentLink, WorkspaceEdit,
|
DocumentHighlight, DocumentLink, WorkspaceEdit,
|
||||||
TextEdit, CodeActionKind,
|
TextEdit, CodeActionKind,
|
||||||
TextDocumentEdit, VersionedTextDocumentIdentifier, DocumentHighlightKind
|
TextDocumentEdit, VersionedTextDocumentIdentifier, DocumentHighlightKind
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -112,6 +112,10 @@ export interface MatchingSchema {
|
||||||
schema: JSONSchema;
|
schema: JSONSchema;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface JSONLanguageStatus {
|
||||||
|
schemas: string[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface LanguageSettings {
|
export interface LanguageSettings {
|
||||||
/**
|
/**
|
||||||
* If set, the validator will return syntax and semantic errors.
|
* If set, the validator will return syntax and semantic errors.
|
||||||
|
@ -158,12 +162,12 @@ export interface SchemaConfiguration {
|
||||||
* The URI of the schema, which is also the identifier of the schema.
|
* The URI of the schema, which is also the identifier of the schema.
|
||||||
*/
|
*/
|
||||||
uri: string;
|
uri: string;
|
||||||
/**
|
/**
|
||||||
* A list of glob patterns that describe for which file URIs the JSON schema will be used.
|
* A list of glob patterns that describe for which file URIs the JSON schema will be used.
|
||||||
* '*' and '**' wildcards are supported. Exclusion patterns start with '!'.
|
* '*' and '**' wildcards are supported. Exclusion patterns start with '!'.
|
||||||
* For example '*.schema.json', 'package.json', '!foo*.schema.json', 'foo/**\/BADRESP.json'.
|
* For example '*.schema.json', 'package.json', '!foo*.schema.json', 'foo/**\/BADRESP.json'.
|
||||||
* A match succeeds when there is at least one pattern matching and last matching pattern does not start with '!'.
|
* A match succeeds when there is at least one pattern matching and last matching pattern does not start with '!'.
|
||||||
*/
|
*/
|
||||||
fileMatch?: string[];
|
fileMatch?: string[];
|
||||||
/**
|
/**
|
||||||
* The schema for the given URI.
|
* The schema for the given URI.
|
||||||
|
|
|
@ -11,7 +11,7 @@ import * as Parser from '../parser/jsonParser';
|
||||||
import { SchemaRequestService, WorkspaceContextService, PromiseConstructor, Thenable, MatchingSchema, TextDocument } from '../jsonLanguageTypes';
|
import { SchemaRequestService, WorkspaceContextService, PromiseConstructor, Thenable, MatchingSchema, TextDocument } from '../jsonLanguageTypes';
|
||||||
|
|
||||||
import * as nls from 'vscode-nls';
|
import * as nls from 'vscode-nls';
|
||||||
import { createRegex} from '../utils/glob';
|
import { createRegex } from '../utils/glob';
|
||||||
|
|
||||||
const localize = nls.loadMessageBundle();
|
const localize = nls.loadMessageBundle();
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ class SchemaHandle implements ISchemaHandle {
|
||||||
return this.resolvedSchema;
|
return this.resolvedSchema;
|
||||||
}
|
}
|
||||||
|
|
||||||
public clearSchema() : boolean {
|
public clearSchema(): boolean {
|
||||||
const hasChanges = !!this.unresolvedSchema;
|
const hasChanges = !!this.unresolvedSchema;
|
||||||
this.resolvedSchema = undefined;
|
this.resolvedSchema = undefined;
|
||||||
this.unresolvedSchema = undefined;
|
this.unresolvedSchema = undefined;
|
||||||
|
@ -545,31 +545,18 @@ export class JSONSchemaService implements IJSONSchemaService {
|
||||||
|
|
||||||
return resolveRefs(schema, schema, schemaURL, dependencies).then(_ => new ResolvedSchema(schema, resolveErrors));
|
return resolveRefs(schema, schema, schemaURL, dependencies).then(_ => new ResolvedSchema(schema, resolveErrors));
|
||||||
}
|
}
|
||||||
|
private getSchemaProperty(document: Parser.JSONDocument): string | undefined {
|
||||||
public getSchemaForResource(resource: string, document?: Parser.JSONDocument): Thenable<ResolvedSchema | undefined> {
|
if (document.root?.type === 'object') {
|
||||||
|
for (const p of document.root.properties) {
|
||||||
// first use $schema if present
|
if (p.keyNode.value === '$schema' && p.valueNode?.type === 'string') {
|
||||||
if (document && document.root && document.root.type === 'object') {
|
return p.valueNode.value;
|
||||||
const schemaProperties = document.root.properties.filter(p => (p.keyNode.value === '$schema') && p.valueNode && p.valueNode.type === 'string');
|
|
||||||
if (schemaProperties.length > 0) {
|
|
||||||
const valueNode = schemaProperties[0].valueNode;
|
|
||||||
if (valueNode && valueNode.type === 'string') {
|
|
||||||
let schemeId = <string>Parser.getNodeValue(valueNode);
|
|
||||||
if (schemeId && Strings.startsWith(schemeId, '.') && this.contextService) {
|
|
||||||
schemeId = this.contextService.resolveRelativePath(schemeId, resource);
|
|
||||||
}
|
|
||||||
if (schemeId) {
|
|
||||||
const id = normalizeId(schemeId);
|
|
||||||
return this.getOrAddSchemaHandle(id).getResolvedSchema();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.cachedSchemaForResource && this.cachedSchemaForResource.resource === resource) {
|
private getAssociatedSchemas(resource: string): string[] {
|
||||||
return this.cachedSchemaForResource.resolvedSchema;
|
|
||||||
}
|
|
||||||
|
|
||||||
const seen: { [schemaId: string]: boolean } = Object.create(null);
|
const seen: { [schemaId: string]: boolean } = Object.create(null);
|
||||||
const schemas: string[] = [];
|
const schemas: string[] = [];
|
||||||
const normalizedResource = normalizeResourceForMatching(resource);
|
const normalizedResource = normalizeResourceForMatching(resource);
|
||||||
|
@ -583,6 +570,33 @@ export class JSONSchemaService implements IJSONSchemaService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return schemas;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getSchemaURIsForResource(resource: string, document?: Parser.JSONDocument): string[] {
|
||||||
|
let schemeId = document && this.getSchemaProperty(document);
|
||||||
|
if (schemeId) {
|
||||||
|
return [schemeId];
|
||||||
|
}
|
||||||
|
return this.getAssociatedSchemas(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getSchemaForResource(resource: string, document?: Parser.JSONDocument): Thenable<ResolvedSchema | undefined> {
|
||||||
|
if (document) {
|
||||||
|
// first use $schema if present
|
||||||
|
let schemeId = this.getSchemaProperty(document);
|
||||||
|
if (schemeId && Strings.startsWith(schemeId, '.') && this.contextService) {
|
||||||
|
schemeId = this.contextService.resolveRelativePath(schemeId, resource);
|
||||||
|
}
|
||||||
|
if (schemeId) {
|
||||||
|
const id = normalizeId(schemeId);
|
||||||
|
return this.getOrAddSchemaHandle(id).getResolvedSchema();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.cachedSchemaForResource && this.cachedSchemaForResource.resource === resource) {
|
||||||
|
return this.cachedSchemaForResource.resolvedSchema;
|
||||||
|
}
|
||||||
|
const schemas = this.getAssociatedSchemas(resource);
|
||||||
const resolvedSchema = schemas.length > 0 ? this.createCombinedSchema(resource, schemas).getResolvedSchema() : this.promise.resolve(undefined);
|
const resolvedSchema = schemas.length > 0 ? this.createCombinedSchema(resource, schemas).getResolvedSchema() : this.promise.resolve(undefined);
|
||||||
this.cachedSchemaForResource = { resource, resolvedSchema };
|
this.cachedSchemaForResource = { resource, resolvedSchema };
|
||||||
return resolvedSchema;
|
return resolvedSchema;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import { JSONSchemaService, ResolvedSchema, UnresolvedSchema } from './jsonSchemaService';
|
import { JSONSchemaService, ResolvedSchema, UnresolvedSchema } from './jsonSchemaService';
|
||||||
import { JSONDocument } from '../parser/jsonParser';
|
import { JSONDocument } from '../parser/jsonParser';
|
||||||
|
|
||||||
import { TextDocument, ErrorCode, PromiseConstructor, Thenable, LanguageSettings, DocumentLanguageSettings, SeverityLevel, Diagnostic, DiagnosticSeverity, Range } from '../jsonLanguageTypes';
|
import { TextDocument, ErrorCode, PromiseConstructor, Thenable, LanguageSettings, DocumentLanguageSettings, SeverityLevel, Diagnostic, DiagnosticSeverity, Range, JSONLanguageStatus } from '../jsonLanguageTypes';
|
||||||
import * as nls from 'vscode-nls';
|
import * as nls from 'vscode-nls';
|
||||||
import { JSONSchemaRef, JSONSchema } from '../jsonSchema';
|
import { JSONSchemaRef, JSONSchema } from '../jsonSchema';
|
||||||
import { isBoolean } from '../utils/objects';
|
import { isBoolean } from '../utils/objects';
|
||||||
|
@ -111,6 +111,10 @@ export class JSONValidation {
|
||||||
return getDiagnostics(schema);
|
return getDiagnostics(schema);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getLanguageStatus(textDocument: TextDocument, jsonDocument: JSONDocument): JSONLanguageStatus {
|
||||||
|
return { schemas: this.jsonSchemaService.getSchemaURIsForResource(textDocument.uri, jsonDocument) };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let idCounter = 0;
|
let idCounter = 0;
|
||||||
|
|
|
@ -10,7 +10,7 @@ import * as fs from 'fs';
|
||||||
import * as url from 'url';
|
import * as url from 'url';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import { getLanguageService, JSONSchema, SchemaRequestService, TextDocument, MatchingSchema } from '../jsonLanguageService';
|
import { getLanguageService, JSONSchema, SchemaRequestService, TextDocument, MatchingSchema } from '../jsonLanguageService';
|
||||||
import { DiagnosticSeverity } from '../jsonLanguageTypes';
|
import { DiagnosticSeverity, SchemaConfiguration } from '../jsonLanguageTypes';
|
||||||
|
|
||||||
function toDocument(text: string, config?: Parser.JSONDocumentConfig, uri = 'foo://bar/file.json'): { textDoc: TextDocument, jsonDoc: Parser.JSONDocument } {
|
function toDocument(text: string, config?: Parser.JSONDocumentConfig, uri = 'foo://bar/file.json'): { textDoc: TextDocument, jsonDoc: Parser.JSONDocument } {
|
||||||
|
|
||||||
|
@ -1459,5 +1459,47 @@ suite('JSON Schema', () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('getLanguageStatus', async function () {
|
||||||
|
const schemas: SchemaConfiguration[] = [{
|
||||||
|
uri: 'https://myschemastore/schema1.json',
|
||||||
|
fileMatch: ['**/*.json'],
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uri: 'https://myschemastore/schema2.json',
|
||||||
|
fileMatch: ['**/bar.json'],
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uri: 'https://myschemastore/schema3.json',
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
const ls = getLanguageService({ workspaceContext });
|
||||||
|
ls.configure({ schemas });
|
||||||
|
|
||||||
|
{
|
||||||
|
const { textDoc, jsonDoc } = toDocument('{ }', undefined, 'foo://bar/folder/foo.json');
|
||||||
|
const info = ls.getLanguageStatus(textDoc, jsonDoc);
|
||||||
|
assert.deepStrictEqual(info.schemas, ['https://myschemastore/schema1.json']);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const { textDoc, jsonDoc } = toDocument('{ }', undefined, 'foo://bar/folder/bar.json');
|
||||||
|
const info = ls.getLanguageStatus(textDoc, jsonDoc);
|
||||||
|
assert.deepStrictEqual(info.schemas, ['https://myschemastore/schema1.json', 'https://myschemastore/schema2.json']);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const { textDoc, jsonDoc } = toDocument('{ $schema: "https://myschemastore/schema3.json" }', undefined, 'foo://bar/folder/bar.json');
|
||||||
|
const info = ls.getLanguageStatus(textDoc, jsonDoc);
|
||||||
|
assert.deepStrictEqual(info.schemas, ['https://myschemastore/schema3.json']);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
Загрузка…
Ссылка в новой задаче