diff --git a/hugo/content/playground/user-validator.ts b/hugo/content/playground/user-validator.ts new file mode 100644 index 00000000..47270102 --- /dev/null +++ b/hugo/content/playground/user-validator.ts @@ -0,0 +1,28 @@ +import { AstNode, AstNodeDescription, AstUtils, DefaultDocumentValidator, DefaultLinker, DiagnosticInfo, DocumentState, DocumentValidator, LangiumDocument, LinkingError, LinkingErrorData, ReferenceInfo, ValidationOptions } from "langium"; +import { LangiumServices } from "langium/lsp"; +import { Diagnostic } from "vscode-languageserver"; + +export class PlaygroundValidator extends DefaultDocumentValidator { + constructor(services: LangiumServices) { + super(services); + } + protected override processLinkingErrors(document: LangiumDocument, diagnostics: Diagnostic[], _options: ValidationOptions): void { + for (const reference of document.references) { + const linkingError = reference.error; + if (linkingError) { + const info: DiagnosticInfo = { + node: linkingError.container, + property: linkingError.property, + index: linkingError.index, + data: { + code: DocumentValidator.LinkingError, + containerType: linkingError.container.$type, + property: linkingError.property, + refText: linkingError.reference.$refText + } satisfies LinkingErrorData + }; + diagnostics.push(this.toDiagnostic('warning', `${linkingError.message}\nIn case you want to adjust the linking rules, please consult the learning section in the Langium documentation.`, info)); + } + } + } +}; diff --git a/hugo/content/playground/user-worker.ts b/hugo/content/playground/user-worker.ts index e752a43d..5660d35f 100644 --- a/hugo/content/playground/user-worker.ts +++ b/hugo/content/playground/user-worker.ts @@ -6,9 +6,10 @@ import { NotificationType } from 'vscode-languageserver/browser.js'; import { DocumentChange, createServerConnection } from './worker-utils.js'; -import { startLanguageServer } from 'langium/lsp'; +import { LangiumServices, startLanguageServer } from 'langium/lsp'; import { DocumentState } from 'langium'; import { createServicesForGrammar } from 'langium/grammar'; +import { PlaygroundValidator } from './user-validator.js'; // listen for messages to trigger starting the LS with a given grammar addEventListener('message', async (event) => { @@ -36,11 +37,17 @@ async function startWithGrammar(grammarText: string): Promise { // create shared services & serializer for the given grammar grammar const { shared, serializer } = await createServicesForGrammar({ grammar: grammarText, + module: { + validation: { + DocumentValidator: (services: LangiumServices) => new PlaygroundValidator(services) + } + }, sharedModule: { + lsp: { Connection: () => connection, } - } + }, }); // listen for validated documents, and send the AST back to the language client