Skip to content

Commit

Permalink
Default dialect config when $schema is not used
Browse files Browse the repository at this point in the history
Co-authored-by: Rajat <rajatkhanduri290102@gmail.com>
Co-authored-by: Diya <diya.solanki.31@gmail.com>
  • Loading branch information
2 people authored and jdesrosiers committed Mar 18, 2024
1 parent 9be8192 commit cbcd257
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 8 deletions.
60 changes: 53 additions & 7 deletions language-server/src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
DiagnosticTag,
DidChangeWatchedFilesNotification,
ProposedFeatures,
DidChangeConfigurationNotification,
SemanticTokensBuilder,
TextDocuments,
TextDocumentSyncKind
Expand Down Expand Up @@ -38,9 +39,13 @@ connection.console.log("Starting JSON Schema service ...");

let hasWorkspaceFolderCapability = false;
let hasWorkspaceWatchCapability = false;
let hasConfigurationCapability = false;

connection.onInitialize(({ capabilities, workspaceFolders }) => {
connection.console.log("Initializing JSON Schema service ...");
hasConfigurationCapability = !!(
capabilities.workspace && !!capabilities.workspace.configuration
);

if (workspaceFolders) {
addWorkspaceFolders(workspaceFolders);
Expand Down Expand Up @@ -73,6 +78,10 @@ connection.onInitialize(({ capabilities, workspaceFolders }) => {
});

connection.onInitialized(async () => {
if (hasConfigurationCapability) {
connection.client.register(DidChangeConfigurationNotification.type);
}

if (hasWorkspaceWatchCapability) {
connection.client.register(DidChangeWatchedFilesNotification.type, {
watchers: [
Expand Down Expand Up @@ -136,6 +145,37 @@ connection.listen();

const documents = new TextDocuments(TextDocument);

// CONFIGURATION

const documentSettings = new Map();
let globalSettings = {};

async function getDocumentSettings(resource) {
if (!hasConfigurationCapability) {
return globalSettings;
}

if (!documentSettings.has(resource)) {
const result = await connection.workspace.getConfiguration({
scopeUri: resource,
section: "jsonSchemaLanguageServer"
});
documentSettings.set(resource, result ?? globalSettings);
}

return documentSettings.get(resource);
}

connection.onDidChangeConfiguration((change) => {
if (hasConfigurationCapability) {
documentSettings.clear();
} else {
globalSettings = change.settings.jsonSchemaLanguageServer ?? globalSettings;
}

validateWorkspace();
});

// INLINE ERRORS

documents.onDidChangeContent(async ({ document }) => {
Expand All @@ -150,19 +190,22 @@ documents.onDidChangeContent(async ({ document }) => {
const validateSchema = async (document) => {
const diagnostics = [];

const settings = await getDocumentSettings(document.uri);
const instance = JsoncInstance.fromTextDocument(document);
if (instance.typeOf() === "undefined") {
return;
}

const $schema = instance.get("#/$schema");
const contextDialectUri = $schema.value();
const contextDialectUri = $schema.value() ?? settings.defaultDialect;
const schemaResources = decomposeSchemaDocument(instance, contextDialectUri);
for (const { dialectUri, schemaInstance } of schemaResources) {
if (!hasDialect(dialectUri)) {
const $schema = schemaInstance.get("#/$schema");
if ($schema.typeOf() === "string") {
diagnostics.push(buildDiagnostic($schema, "Unknown dialect"));
} else if (contextDialectUri) {
diagnostics.push(buildDiagnostic(schemaInstance, "Unknown dialect"));
} else {
diagnostics.push(buildDiagnostic(schemaInstance, "No dialect"));
}
Expand Down Expand Up @@ -260,9 +303,10 @@ const getTokenBuilder = (uri) => {
return result;
};

const buildTokens = (builder, document) => {
const buildTokens = (builder, document, settings) => {
const instance = JsoncInstance.fromTextDocument(document);
const dialectUri = instance.get("#/$schema").value();
const $schema = instance.get("#/$schema");
const dialectUri = $schema.value() ?? settings.defaultDialect;
const schemaResources = decomposeSchemaDocument(instance, dialectUri);
for (const { keywordInstance, tokenType, tokenModifier } of getSemanticTokens(schemaResources)) {
const startPosition = keywordInstance.startPosition();
Expand All @@ -276,31 +320,33 @@ const buildTokens = (builder, document) => {
}
};

connection.languages.semanticTokens.on(({ textDocument }) => {
connection.languages.semanticTokens.on(async ({ textDocument }) => {
connection.console.log(`semanticTokens.on: ${textDocument.uri}`);

if (isSchema(textDocument.uri)) {
const builder = getTokenBuilder(textDocument.uri);
const document = documents.get(textDocument.uri);
buildTokens(builder, document);
const settings = await getDocumentSettings(document.uri);
buildTokens(builder, document, settings);

return builder.build();
} else {
return { data: [] };
}
});

connection.languages.semanticTokens.onDelta(({ textDocument, previousResultId }) => {
connection.languages.semanticTokens.onDelta(async ({ textDocument, previousResultId }) => {
connection.console.log(`semanticTokens.onDelta: ${textDocument.uri}`);

const document = documents.get(textDocument.uri);
const settings = await getDocumentSettings(document.uri);
if (document === undefined) {
return { edits: [] };
}

const builder = getTokenBuilder(document);
builder.previousResult(previousResultId);
buildTokens(builder, document);
buildTokens(builder, document, settings);

return builder.buildEdits();
});
Expand Down
11 changes: 10 additions & 1 deletion vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,14 @@
"onLanguage:json"
],
"contributes": {
"configuration": {
"title": "Configuration for JSON Schema Language Server",
"properties": {
"jsonSchemaLanguageServer.defaultDialect": {
"type": "string",
"description": "The default JSON Schema dialect to use if none is specified in the schema document"
}
}
}
}
}
}

0 comments on commit cbcd257

Please sign in to comment.