Skip to content

Commit

Permalink
Make a class for configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
jdesrosiers committed Sep 9, 2024
1 parent 339ac62 commit 8dd3202
Show file tree
Hide file tree
Showing 25 changed files with 201 additions and 169 deletions.
16 changes: 9 additions & 7 deletions language-server/src/build-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import "@hyperjump/json-schema/draft-07";
import "@hyperjump/json-schema/draft-06";
import "@hyperjump/json-schema/draft-04";
import { SchemaRegistry } from "./schema-registry.js";
import { Configuration } from "./configuration.js";

/**
* @import { Connection, InitializeParams, ServerCapabilities } from "vscode-languageserver"
Expand All @@ -15,10 +16,10 @@ import { SchemaRegistry } from "./schema-registry.js";

/**
* @typedef {{
* load: (connection: Connection, schemas: SchemaRegistry) => void;
* load: (connection: Connection, schemas: SchemaRegistry, configuration: Configuration) => void;
* onInitialize: (params: InitializeParams, connection: Connection, schemas: SchemaRegistry) => ServerCapabilities;
* onInitialized: (connection: Connection, schemas: SchemaRegistry) => Promise<void>;
* onShutdown: (connection: Connection, schemas: SchemaRegistry) => Promise<void>;
* onInitialized: (connection: Connection, schemas: SchemaRegistry, configuration: Configuration) => Promise<void>;
* onShutdown: (connection: Connection, schemas: SchemaRegistry, configuration: Configuration) => Promise<void>;
* }} Feature
*/

Expand All @@ -27,10 +28,11 @@ removeMediaTypePlugin("https");

/** @type (connection: Connection, features: Feature[]) => void */
export const buildServer = (connection, features) => {
const schemas = new SchemaRegistry(connection);
const configuration = new Configuration(connection);
const schemas = new SchemaRegistry(connection, configuration);

for (const feature of features) {
feature.load(connection, schemas);
feature.load(connection, schemas, configuration);
}

connection.onInitialize(async (params) => {
Expand All @@ -45,13 +47,13 @@ export const buildServer = (connection, features) => {

connection.onInitialized(async () => {
for (const feature of features) {
await feature.onInitialized(connection, schemas);
await feature.onInitialized(connection, schemas, configuration);
}
});

connection.onShutdown(async () => {
for (const feature of features) {
await feature.onShutdown(connection, schemas);
await feature.onShutdown(connection, schemas, configuration);
}
});

Expand Down
80 changes: 80 additions & 0 deletions language-server/src/configuration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { fileURLToPath } from "node:url";
import picomatch from "picomatch";

/**
* @import { Connection, DidChangeConfigurationParams, NotificationHandler } from "vscode-languageserver"
*/


/**
* @typedef {{
* defaultDialect?: string;
* schemaFilePatterns: string[];
* }} DocumentSettings
*/

export class Configuration {
#connection;

/** @type DocumentSettings | undefined */
#settings;
/** @type Partial<DocumentSettings> */
#defaultSettings;

/** @type ((uri: string) => boolean) | undefined */
#matcher;

/** @type NotificationHandler<DidChangeConfigurationParams>[] */
#didChangeConfigurationHandlers;

/**
* @param {Connection} connection
*/
constructor(connection) {
this.#connection = connection;

this.#defaultSettings = {
schemaFilePatterns: ["**/*.schema.json", "**/schema.json"]
};

this.#didChangeConfigurationHandlers = [];

this.#connection.onDidChangeConfiguration((params) => {
this.#settings = { ...this.#defaultSettings, ...params.settings.jsonSchemaLanguageServer };
this.#matcher = undefined;

for (const handler of this.#didChangeConfigurationHandlers) {
handler(params);
}
});
}

/** @type () => Promise<DocumentSettings> */
async get() {
if (!this.#settings) {
const result = await this.#connection.workspace.getConfiguration({
section: "jsonSchemaLanguageServer"
}) ?? {};
this.#settings = { ...this.#defaultSettings, ...result };
this.#matcher = undefined;
}

return /** @type DocumentSettings */ (this.#settings);
}

/** @type (uri: string) => Promise<boolean> */
async isSchema(uri) {
if (!this.#matcher) {
const { schemaFilePatterns } = await this.get();
this.#matcher = picomatch(schemaFilePatterns);
}

const path = fileURLToPath(uri);
return this.#matcher(path);
}

/** @type (handler: NotificationHandler<DidChangeConfigurationParams>) => void */
onDidChangeConfiguration(handler) {
this.#didChangeConfigurationHandlers.push(handler);
}
}
2 changes: 1 addition & 1 deletion language-server/src/features/completion.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { afterAll, beforeAll, describe, expect, test } from "vitest";
import { TestClient } from "../test-client.js";
import completion from "./completion.js";

import type { DocumentSettings } from "./document-settings.js";
import type { DocumentSettings } from "../configuration.js";


describe("Feature - Completion", () => {
Expand Down
2 changes: 1 addition & 1 deletion language-server/src/features/custom-dialects.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import validationErrorsFeature from "./validation-errors.js";
import workspace from "./workspace.js";

import type { Diagnostic } from "vscode-languageserver";
import type { DocumentSettings } from "./document-settings.js";
import type { DocumentSettings } from "../configuration.js";


describe("Feature - Custom Dialects", () => {
Expand Down
2 changes: 1 addition & 1 deletion language-server/src/features/definition.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import documentSettings from "./document-settings.js";
import workspace from "./workspace.js";
import definitionFeature from "./definition.js";

import type { DocumentSettings } from "./document-settings.js";
import type { DocumentSettings } from "../configuration.js";


describe("Feature - Goto Definition", () => {
Expand Down
2 changes: 1 addition & 1 deletion language-server/src/features/deprecated.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import validateSchema from "./validate-schema.js";
import workspace from "./workspace.js";

import type { Diagnostic } from "vscode-languageserver";
import type { DocumentSettings } from "./document-settings.js";
import type { DocumentSettings } from "../configuration.js";


describe("Feature - Deprecated", () => {
Expand Down
61 changes: 2 additions & 59 deletions language-server/src/features/document-settings.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,16 @@
import { DidChangeConfigurationNotification } from "vscode-languageserver";
import { fileURLToPath } from "node:url";
import picomatch from "picomatch";
import { publishAsync } from "../pubsub.js";

/**
* @import { Connection } from "vscode-languageserver"
* @import { Feature } from "../build-server.js"
*/


/**
* @typedef {{
* defaultDialect?: string;
* schemaFilePatterns: string[];
* }} DocumentSettings
*/

let hasDidChangeConfigurationCapability = false;

/** @type Feature */
export default {
load(connection, schemas) {
matcher = new Promise((resolve) => {
connection.onDidChangeConfiguration(async ({ settings }) => {
documentSettings.clear();
schemas.clear();

const fullSettings = { ...defaultSettings, ...settings.jsonSchemaLanguageServer };
matcher = Promise.resolve(picomatch(fullSettings.schemaFilePatterns));
resolve(matcher);

await publishAsync("workspaceChanged", { changes: [] });
});
});

schemas.onDidClose(({ document }) => {
documentSettings.delete(document.textDocument.uri);
});
// TODO: Can this be merged with Configuration?
load() {
},

onInitialize({ capabilities }) {
Expand All @@ -50,40 +24,9 @@ export default {
await connection.client.register(DidChangeConfigurationNotification.type, {
section: "jsonSchemaLanguageServer"
});
} else {
matcher = Promise.resolve(picomatch(defaultSettings.schemaFilePatterns));
}
},

async onShutdown() {
}
};

// TODO: DocumentSettings class

const documentSettings = new Map();
const defaultSettings = {
schemaFilePatterns: ["**/*.schema.json", "**/schema.json"]
};

/** @type (connection: Connection, uri?: string) => Promise<DocumentSettings> */
export const getDocumentSettings = async (connection, uri) => {
if (!documentSettings.has(uri)) {
const result = await connection.workspace.getConfiguration({
scopeUri: uri,
section: "jsonSchemaLanguageServer"
}) ?? {};
documentSettings.set(uri, { ...defaultSettings, ...result });
}

return documentSettings.get(uri);
};

/** @type Promise<(uri: string) => boolean> */
let matcher;

/** @type (uri: string) => Promise<boolean> */
export const isSchema = async (uri) => {
const path = fileURLToPath(uri);
return (await matcher)(path);
};
2 changes: 1 addition & 1 deletion language-server/src/features/document-settings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import validationErrors from "./validation-errors.js";
import workspace from "./workspace.js";

import type { Diagnostic } from "vscode-languageserver";
import type { DocumentSettings } from "./document-settings.js";
import type { DocumentSettings } from "../configuration.js";


describe("Feature - Document Settings", () => {
Expand Down
2 changes: 1 addition & 1 deletion language-server/src/features/hover.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { TestClient } from "../test-client.js";
import hover from "./hover.js";

import type { Hover, MarkupContent } from "vscode-languageserver";
import type { DocumentSettings } from "./document-settings.js";
import type { DocumentSettings } from "../configuration.js";


describe("Feature - Hover", () => {
Expand Down
2 changes: 1 addition & 1 deletion language-server/src/features/if-then-completion.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { TestClient } from "../test-client.js";
import completion from "./completion.js";
import ifThenCompletionFeature, { ifThenPatternCompletion } from "./if-then-completion.js";

import type { DocumentSettings } from "./document-settings.js";
import type { DocumentSettings } from "../configuration.js";


describe("Feature - if/then completion", () => {
Expand Down
2 changes: 1 addition & 1 deletion language-server/src/features/keywords-completion.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { TestClient } from "../test-client.js";
import completion from "./completion.js";
import keywordsCompletionFeature from "./keywords-completion.js";

import type { DocumentSettings } from "./document-settings.js";
import type { DocumentSettings } from "../configuration.js";


describe("Feature - if/then completion", () => {
Expand Down
2 changes: 1 addition & 1 deletion language-server/src/features/references.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import documentSettings from "./document-settings.js";
import workspace from "./workspace.js";
import ReferencesFeature from "./references.js";

import type { DocumentSettings } from "./document-settings.js";
import type { DocumentSettings } from "../configuration.js";


describe("Feature - References", () => {
Expand Down
2 changes: 1 addition & 1 deletion language-server/src/features/schema-completion.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { TestClient } from "../test-client.js";
import completion from "./completion.js";
import schemaCompletion from "./schema-completion.js";

import type { DocumentSettings } from "./document-settings.js";
import type { DocumentSettings } from "../configuration.js";


describe("Feature - $schema completion", () => {
Expand Down
5 changes: 2 additions & 3 deletions language-server/src/features/semantic-tokens.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { SemanticTokensBuilder } from "vscode-languageserver";
import { isSchema } from "./document-settings.js";

/**
* @import { SemanticTokensClientCapabilities, SemanticTokensLegend } from "vscode-languageserver"
Expand All @@ -25,7 +24,7 @@ import { isSchema } from "./document-settings.js";

/** @type Feature */
export default {
load(connection, schemas) {
load(connection, schemas, configuration) {
const tokenBuilders = new Map();

schemas.onDidClose(({ document }) => {
Expand Down Expand Up @@ -63,7 +62,7 @@ export default {
};

connection.languages.semanticTokens.on(async ({ textDocument }) => {
if (!await isSchema(textDocument.uri)) {
if (!await configuration.isSchema(textDocument.uri)) {
return { data: [] };
}

Expand Down
2 changes: 1 addition & 1 deletion language-server/src/features/semantic-tokens.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import documentSettings from "./document-settings.js";
import semanticTokens from "./semantic-tokens.js";
import workspace from "./workspace.js";

import type { DocumentSettings } from "./document-settings.js";
import type { DocumentSettings } from "../configuration.js";


describe("Feature - Semantic Tokens", () => {
Expand Down
2 changes: 1 addition & 1 deletion language-server/src/features/validate-references.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import validateSchema from "./validate-schema.js";
import validateReferencesFeature from "./validate-references.js";

import type { Diagnostic } from "vscode-languageserver";
import type { DocumentSettings } from "./document-settings.js";
import type { DocumentSettings } from "../configuration.js";


describe("Feature - Validate References Errors", () => {
Expand Down
1 change: 1 addition & 0 deletions language-server/src/features/validate-schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export default {
await publishAsync("validateSchema", document);
});

// TODO: Can this be done without pubsub?
subscriptionToken = subscribe("validateSchema", async (_message, /** @type SchemaDocumentType */ schemaDocument) => {
connection.console.log(`Validate Schema: ${schemaDocument.textDocument.uri}`);

Expand Down
2 changes: 1 addition & 1 deletion language-server/src/features/validate-vocabulary.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import validateSchema from "./validate-schema.js";
import validationErrors from "./validation-errors.js";
import workspace from "./workspace.js";

import type { DocumentSettings } from "./document-settings.js";
import type { Diagnostic } from "vscode-languageserver";
import type { DocumentSettings } from "../configuration.js";


describe("Feature - Validate $vocabulary", () => {
Expand Down
Loading

0 comments on commit 8dd3202

Please sign in to comment.