Skip to content

Commit

Permalink
Fix the Initialized race condition problem
Browse files Browse the repository at this point in the history
The only place this doesn't work is the node-based workspace watcher
used for neovim.
  • Loading branch information
jdesrosiers committed Jun 21, 2024
1 parent d1c2297 commit e1ad38d
Show file tree
Hide file tree
Showing 14 changed files with 167 additions and 128 deletions.
6 changes: 5 additions & 1 deletion language-server/src/build-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ import "@hyperjump/json-schema/draft-04";
export const buildServer = (connection, features) => {
const documents = new TextDocuments(TextDocument);

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

connection.onInitialize((params) => {
connection.console.log("Initializing JSON Schema service ...");

Expand All @@ -24,7 +28,7 @@ export const buildServer = (connection, features) => {

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

Expand Down
23 changes: 13 additions & 10 deletions language-server/src/features/completion.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,7 @@ import { getSchemaDocument } from "./schema-registry.js";


export default {
onInitialize() {
return {
completionProvider: {
resolveProvider: false,
triggerCharacters: ["\"", ":", " "]
}
};
},

onInitialized(connection, documents) {
load(connection, documents) {
connection.onCompletion(async ({ textDocument, position }) => {
const document = documents.get(textDocument.uri);
const schemaDocument = await getSchemaDocument(connection, document);
Expand All @@ -22,5 +13,17 @@ export default {
await publishAsync("completions", { schemaDocument, offset, completions });
return completions;
});
},

onInitialize() {
return {
completionProvider: {
resolveProvider: false,
triggerCharacters: ["\"", ":", " "]
}
};
},

onInitialized() {
}
};
13 changes: 8 additions & 5 deletions language-server/src/features/deprecated.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@ import { subscribe } from "../pubsub.js";
const annotationDialectUri = "https://json-schema.org/draft/2020-12/schema";

export default {
onInitialize() {
return {};
},

onInitialized() {
load() {
subscribe("diagnostics", async (_message, { schemaDocument, diagnostics }) => {
for (const schemaResource of schemaDocument.schemaResources) {
for (const deprecated of SchemaNode.annotatedWith(schemaResource, "deprecated", annotationDialectUri)) {
Expand All @@ -25,5 +21,12 @@ export default {
}
}
});
},

onInitialize() {
return {};
},

onInitialized() {
}
};
26 changes: 14 additions & 12 deletions language-server/src/features/document-settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,7 @@ let hasConfigurationCapability = false;
let hasDidChangeConfigurationCapability = false;

export default {
onInitialize: ({ capabilities }) => {
hasConfigurationCapability = !!capabilities.workspace?.configuration;
hasDidChangeConfigurationCapability = !!capabilities.workspace?.didChangeConfiguration?.dynamicRegistration;

return {};
},

onInitialized: (connection, documents) => {
if (hasDidChangeConfigurationCapability) {
connection.client.register(DidChangeConfigurationNotification.type);
}

load(connection, documents) {
connection.onDidChangeConfiguration(() => {
if (hasConfigurationCapability) {
documentSettings.clear();
Expand All @@ -31,6 +20,19 @@ export default {
documents.onDidClose(({ document }) => {
documentSettings.delete(document.uri);
});
},

onInitialize({ capabilities }) {
hasConfigurationCapability = !!capabilities.workspace?.configuration;
hasDidChangeConfigurationCapability = !!capabilities.workspace?.didChangeConfiguration?.dynamicRegistration;

return {};
},

onInitialized(connection) {
if (hasDidChangeConfigurationCapability) {
connection.client.register(DidChangeConfigurationNotification.type);
}
}
};

Expand Down
17 changes: 10 additions & 7 deletions language-server/src/features/hover.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,7 @@ import { getSchemaDocument } from "./schema-registry.js";
const annotationDialectUri = "https://json-schema.org/draft/2020-12/schema";

export default {
onInitialize() {
return {
hoverProvider: true
};
},

onInitialized(connection, documents) {
load(connection, documents) {
connection.onHover(async ({ textDocument, position }) => {
const document = documents.get(textDocument.uri);
const schemaDocument = await getSchemaDocument(connection, document);
Expand All @@ -35,5 +29,14 @@ export default {
};
}
});
},

onInitialize() {
return {
hoverProvider: true
};
},

onInitialized() {
}
};
13 changes: 8 additions & 5 deletions language-server/src/features/if-then-completion.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@ import { subscribe } from "../pubsub.js";


export default {
onInitialize() {
return {};
},

onInitialized() {
load() {
subscribe("completions", async (_message, { schemaDocument, offset, completions }) => {
const currentProperty = SchemaDocument.findNodeAtOffset(schemaDocument, offset);
if (currentProperty && currentProperty.pointer.endsWith("/if") && currentProperty.type === "property") {
completions.push(...ifThenPatternCompletion);
}
});
},

onInitialize() {
return {};
},

onInitialized() {
}
};

Expand Down
13 changes: 8 additions & 5 deletions language-server/src/features/schema-completion.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ import { subscribe } from "../pubsub.js";


export default {
onInitialize() {
return {};
},

onInitialized() {
load() {
const trailingHashDialects = new Set([
"http://json-schema.org/draft-04/schema",
"http://json-schema.org/draft-06/schema",
Expand All @@ -26,5 +22,12 @@ export default {
})));
}
});
},

onInitialize() {
return {};
},

onInitialized() {
}
};
11 changes: 7 additions & 4 deletions language-server/src/features/schema-registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ import * as SchemaDocument from "../schema-document.js";


export default {
load(_connection, documents) {
documents.onDidClose(({ document }) => {
schemaDocuments.delete(document.uri);
});
},

onInitialize() {
return {};
},

onInitialized(_connection, documents) {
documents.onDidClose(({ document }) => {
schemaDocuments.delete(document.uri);
});
onInitialized() {
}
};

Expand Down
29 changes: 16 additions & 13 deletions language-server/src/features/semantic-tokens.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,7 @@ import { getDocumentSettings } from "./document-settings.js";


export default {
onInitialize({ capabilities }) {
return {
semanticTokensProvider: {
legend: buildSemanticTokensLegend(capabilities.textDocument?.semanticTokens),
range: false,
full: {
delta: true
}
}
};
},

onInitialized(connection, documents) {
load(connection, documents) {
const tokenBuilders = new Map();

documents.onDidClose(({ document }) => {
Expand Down Expand Up @@ -73,6 +61,21 @@ export default {

return builder.buildEdits();
});
},

onInitialize({ capabilities }) {
return {
semanticTokensProvider: {
legend: buildSemanticTokensLegend(capabilities.textDocument?.semanticTokens),
range: false,
full: {
delta: true
}
}
};
},

onInitialized() {
}
};

Expand Down
13 changes: 8 additions & 5 deletions language-server/src/features/validate-references.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@ import { keywordNameFor } from "../util.js";


export default {
onInitialize() {
return {};
},

onInitialized() {
load() {
subscribe("diagnostics", async (_message, { schemaDocument, diagnostics }) => {
for (const schemaResource of schemaDocument.schemaResources) {
for (const node of references(schemaResource)) {
Expand All @@ -20,6 +16,13 @@ export default {
}
}
});
},

onInitialize() {
return {};
},

onInitialized() {
}
};

Expand Down
13 changes: 8 additions & 5 deletions language-server/src/features/validation-errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@ import { subscribe } from "../pubsub.js";


export default {
onInitialize() {
return {};
},

onInitialized() {
load() {
subscribe("diagnostics", async (_message, { schemaDocument, diagnostics }) => {
for await (const [instance, message] of invalidNodes(schemaDocument.errors)) {
diagnostics.push({ instance, message });
}
});
},

onInitialize() {
return {};
},

onInitialized() {
}
};

Expand Down
10 changes: 10 additions & 0 deletions language-server/src/features/workspace-neovim.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ describe("Feature - workspace (neovim)", () => {
]
};
capabilities = await initializeServer(client, init);

// Block for a while to allow InitializedNotification time to finish. This
// is only needed for the node-based workspace watching used for neovim
await wait(10);
});

afterAll(async () => {
Expand Down Expand Up @@ -87,6 +91,12 @@ describe("Feature - workspace (neovim)", () => {
});
});

const wait = async (delay) => {
return new Promise((resolve) => {
setTimeout(resolve, delay);
});
};

const touch = (path) => {
const time = new Date();
return utimes(path, time, time);
Expand Down
Loading

0 comments on commit e1ad38d

Please sign in to comment.